Impact of 401(k) on Financial Assets

Impact of 401(k) on Financial Assets

Data explanation

1991 Survey of Income and Program Participation

  • net_tfaNet Total Financial Assets. Calculated as the sum of all liquid and interest-earning assets (IRA balances, 401(k) balances, checking accounts, U.S. savings bonds, other interest‐earning accounts, stocks, mutual funds, etc.) minus non‐mortgage debts.

  • e401401(k) Eligibility Indicator. Equals 1 if the individual's employer offers a 401(k) plan; otherwise 0.

  • p401401(k) Participation Indicator. Equals 1 if the individual participate in 401(k) plan; otherwise 0.

  • ageAge. Age of the individual in years.

  • incAnnual Income. Annual income of the individual, measured in U.S. dollars for the year 1990.

  • educYears of Education. Number of completed years of formal education.

  • fsizeFamily Size. Total number of persons living in the household.

  • marrMarital Status. Equals 1 if the individual is married; otherwise 0.

  • twoearnTwo-Earner Household. Equals 1 if there are two wage earners in the household; otherwise 0.

  • dbDefined-Benefit Pension Plan. Equals 1 if the individual is covered by a defined-benefit pension plan; otherwise 0.

  • piraIRA Participation. Equals 1 if the individual contributes to an Individual Retirement Account (IRA); otherwise 0.

  • hownHome Ownership. Equals 1 if the household owns its home; 0 if renting.

We download it with fetch_401K function from doubleML.datasets

This dataset has a problem. Cofounders were measured in the same year as treatment and outcome, like they are demographic factors that do not change over time. So inference might still be biased.

Result

Index(['net_tfa', 'age', 'inc', 'fsize', 'educ', 'db', 'marr', 'twoearn', 'p401', 'pira', 'hown'], dtype='object')

EDA

Result

{'n_rows': 9915, 'n_columns': 11}

Result
countmeanstdminp10p25medianp75p90max
treatment
0732110890.47753955256.829173-502302.0-5427.0-1184.0200.07399.033500.01462115.0
1259438262.05859479087.535303-283356.0-1300.03000.015249.045985.598887.41536798.0

Participants’ average net worth is ≈28k higher, but this gap cannot be causally attributed solely to participation. The classes are imbalanced—only 26% are treated.

Result

png

Result

png

Our outcome has large right tail

Result
mean_t_0mean_t_1abs_diffsmd
confounders
inc32889.80248649366.97571316477.1732270.662197
hown0.5891270.7652270.1761000.383456
pira0.2002460.3604470.1602010.362421
db0.2282480.3916730.1634260.358968
twoearn0.3376590.5026990.1650400.339096
educ12.99112113.8134160.8222940.299061
marr0.5745120.6904390.1159280.242175
age40.90097041.5096380.6086680.060108
fsize2.8481082.9159600.0678520.044731

Treatment and control are unbalanced on all confounders except age and fsize; nonetheless, we retain age and fsize in the model to gain efficiency

Result

ROC AUC from PropensityModel: 0.7145

Result

Positivity check from PropensityModel: {'bounds': (0.05, 0.95), 'share_below': 0.08371154815935451, 'share_above': 0.0, 'flag': True}

Result
featureshap_meanshap_mean_absexact_pp_change_absexact_pp_change_signed
0num__inc0.0069320.5833190.1262030.001334
1num__fsize0.0054610.0805930.0157780.001050
2num__age-0.0045830.1543120.030720-0.000879
3num__marr-0.0045240.0301190.005827-0.000868
4num__educ-0.0037600.1210980.023929-0.000722
5num__hown0.0010240.1872550.0375510.000197
6num__db-0.0008160.2723250.055610-0.000157
7num__twoearn0.0002280.0431590.0083760.000044
8num__pira0.0000380.1295440.0256470.000007
Result

png

Result

{'rmse': 60189.944724760215, 'mae': 20331.55384475013}

Result
featureshap_mean
0inc731.774932
1pira-683.388458
2age370.619026
3marr-189.688960
4educ-133.732826
5twoearn-106.324198
6fsize68.288189
7db-32.271609
8hown-25.276096

Inference

Result

11250.6922050985 4.0745185003743245e-13 (8210.458854591107, 14290.925555605892)

Average Treatment Effect is significant and equals 11385 dollars in CI bounds (8674, 14096)

Refutation

Overlap validation

Result
metricvalueflag
0edge_0.01_below0.000000GREEN
1edge_0.01_above0.000000GREEN
2edge_0.02_below0.026828GREEN
3edge_0.02_above0.000000GREEN
4KS0.307200YELLOW
5AUC0.706812GREEN
6ESS_treated_ratio0.365399GREEN
7ESS_control_ratio0.893936GREEN
8tails_w1_q99/med33.171484YELLOW
9tails_w0_q99/med5.250310GREEN
10ATT_identity_relerr0.069338YELLOW
11clip_m_total0.009783GREEN
12calib_ECE0.026384GREEN
13calib_slope0.765845YELLOW
14calib_intercept-0.197527GREEN

We find no evidence of a violation of the overlap (positivity) assumption.

Score validation

Result
metricvalueflag
0se_plugin1551.167968NA
1psi_p99_over_med36.192430RED
2psi_kurtosis263.310341RED
3max_|t|_g13.951050YELLOW
4max_|t|_g02.472043YELLOW
5max_|t|_m1.875749GREEN
6oos_tstat_fold0.000028GREEN
7oos_tstat_strict0.000028GREEN

We see that psi_p99_over_med and psi_kurtosis are RED. That's because large tail in outcome. We find no evidence of anomaly score behavior

SUTVA

Result

1.) Are your clients independent (i)? 2.) Do you measure confounders, treatment, and outcome in the same intervals? 3.) Do you measure confounders before treatment and outcome after? 4.) Do you have a consistent label of treatment, such as if a person does not receive a treatment, he has a label 0?

1.) Yes
2.) Yes
3.) No. We have problems with design
4.) Yes
In conclusion cofounders are measured not before treatment. So treatment affected cofounders

Uncofoundedness

Result
metricvalueflag
0balance_max_smd7.606060e-02GREEN
1balance_frac_violations0.000000e+00GREEN
2ess_treated_ratio3.653986e-01RED
3ess_control_ratio8.939358e-01GREEN
4w_tail_ratio_treated1.218068e+13RED
5w_tail_ratio_control2.482226e+00GREEN
6top1_mass_share_treated2.137807e-01GREEN
7top1_mass_share_control3.937273e-02GREEN
8ks_m_treated_vs_control3.071998e-01YELLOW
9pct_m_outside_overlap9.783157e-01GREEN

We see w_tail_ratio_treated and ess_treated_ratio are RED. It's ok. These tests are unstable due to small sample

Result

{'theta': 11250.6922050985, 'se': 1551.1679676200004, 'level': 0.95, 'z': 1.959963984540054, 'sampling_ci': (8210.458854591107, 14290.925555605892), 'theta_bounds_confounding': (10298.960958424657, 12202.423451772342), 'bias_aware_ci': (7258.727607917263, 15242.656802279736), 'max_bias': 951.7312466738426, 'sigma2': 3589568447.751854, 'nu2': 0.37645320639967106, 'params': {'cf_y': 0.01, 'cf_d': 0.01, 'rho': 1.0, 'use_signed_rr': True}}

Even when we have unobserved cofounder with these parameters our CI bounds > 0

Result

/Users/ioannmartynov/PycharmProjects/Ckit/causalis/data/causaldata.py:108: UserWarning: Found 112 duplicate rows out of 9915 total rows in the DataFrame. This leaves 9803 unique rows for analysis. Duplicate rows may affect the quality of causal inference results. Consider removing duplicates if they are not intentional. self._check_duplicate_rows(self.df)

cf_ycf_drhotheta_longtheta_shortdelta
p4010.0000410.000004-1.011250.69220514355.071728-3104.379523

And even when unobserved cofounder is strong as 'inc' - income our estimate has CI bounds > 0

Conclution

There are problems with design: cofounders are measured not before treatment. So treatment affected cofounders. However estimate is robust and in real life participation in 401k is increasing net financial assets. To keep in mind real CI bounds may differ from our estimation