Skip to content
Research2 min read

DML IRM vs CausalML NearestNeighborMatch

This notebook presents the matching research workflow and key analysis steps.

DML IRM vs CausalML NearestNeighborMatch

This notebook presents the matching research workflow and key analysis steps.

Causal Inference consists of two main parts: Identification Assumptions and Model Specification. SUTVA, Unconfoundedness, Overlap are strong assumptions that must be true to call our inference causal. Studies and quasi experiments often have problems with Identification Assumptions so in practice you spend time to prove them, not model specification

However, In this notebook I will focus on the model specification. Propensity Score matching is a classical ML non-parametric approcah, estimating ATTE. It must perform worse than DML approach because:

  • uses both the propensity model and the outcome model, not just propensity scores

  • is more robust to small model misspecification through orthogonalization

  • uses cross-fitting, which reduces overfitting bias from ML nuisance models

  • does not throw away as much data as matching often does

  • provides more principled statistical inference (standard errors, confidence intervals)

  • can estimate ATE or ATTE cleanly, not just the treated-group effect by default

We will compare absolute estimates on DGPs from Causalis between IRM DML model implemented in Causalis and NearestNeighborMatch implemented in CausalML

generate_obs_hte_26_rich()

Read more about dgp at https://causalis.causalcraft.com/articles/generate_obs_hte_26_rich

Result

Running n=10,000 ... Running n=100,000 ... Running n=1,000,000 ...

nground_truth_atteirm_attematching_atteirm_abs_errormatching_abs_errorirm_runtime_secmatching_runtime_secmatched_n
01000011.4544046.25608735.9781895.19831724.5237853.3254421.350460618
110000010.91499112.10685628.7210691.19186417.80607716.5880173.7407189238
2100000011.02812910.34054216.5892850.6875875.561156220.50111635.60444799218
Result

n=10,000: ground truth ATTE=11.454404, IRM ATTE=6.256087, matching ATTE=35.978189 n=100,000: ground truth ATTE=10.914991, IRM ATTE=12.106856, matching ATTE=28.721069 n=1,000,000: ground truth ATTE=11.028129, IRM ATTE=10.340542, matching ATTE=16.589285

DML IRM outperforms NearestNeighborMatch

generate_obs_hte_binary_26()

read more about the dgp at https://causalis.causalcraft.com/articles/generate_obs_hte_binary_26

Result

Running n=10,000 ... Running n=100,000 ... Running n=1,000,000 ...

nground_truth_atteirm_attematching_atteirm_abs_errormatching_abs_errorirm_runtime_secmatching_runtime_secmatched_n
0100000.1038850.1023440.1156520.0015410.0117674.4763671.9707282594
11000000.1012380.1035470.0740510.0023090.02718727.5494544.83042029304
210000000.1014110.1032820.0942180.0018710.007192221.72027835.615880298710
Result

n=10,000: ground truth ATTE=0.103885, IRM ATTE=0.102344, matching ATTE=0.115652 n=100,000: ground truth ATTE=0.101238, IRM ATTE=0.103547, matching ATTE=0.074051 n=1,000,000: ground truth ATTE=0.101411, IRM ATTE=0.103282, matching ATTE=0.094218

DML IRM outperforms NearestNeighborMatch

Conclusion

I recommend to use DML IRM for Unconfoundedness scenario as default model specification