chc.lalonde¶
Stability tier: experimental.
LaLonde-Dehejia-Wahba job-training benchmark: a randomized ATE recovered from confounded data.
The National Supported Work (NSW) demonstration randomized a job-training treatment; its
experimental effect on 1978 earnings is ~$1794 (Dehejia & Wahba 1999) -- an author-independent
truth, not a self-authored DGP. The LaLonde (1986) challenge swaps the experimental controls for a
non-experimental CPS comparison pool: the naive treated-minus-control gap is then catastrophically
biased (wrong sign, ~ -$8500), and a causal estimator's job is to recover the experimental number by
covariate adjustment. This exercises CHC's causal backbone (chc.estimators) on real external
data -- an external-validity check.
Data (public domain, ~445 + 15992 rows) is fetched from the Rdatasets mirror on first use and cached
under ~/.cache/chc; no dataset ships in the repo and no package dependency is added (urllib +
NumPy only). Gated like the BOPTEST tasks: if the fetch fails (offline), callers skip.
LalondeData
dataclass
¶
The observational LaLonde sample (NSW-treated + CPS controls) plus the randomized truth.
naive_ate
property
¶
Unadjusted treated-minus-control earnings gap -- badly confounded on the CPS pool.
load_lalonde(cache_dir=None)
¶
Load the LaLonde benchmark: experimental NSW ATE + the confounded observational sample.
Fetches nsw_mixtape (randomized) and cps_mixtape (CPS controls) from Rdatasets, caching
under cache_dir (default ~/.cache/chc). Raises on a failed fetch -- callers skip
when offline, like the BOPTEST tasks.
lalonde_ate(data, estimator)
¶
Adjusted ATE (dollars) from a CHC estimator on the confounded observational sample.
Covariates are standardised (raw re74/re75 earnings would blow up polynomial nuisances)
and the outcome scaled to $1000s for conditioning, then the estimate scaled back to dollars.
Each covariate reaches the estimator at unit spread in any units, and one whose spread is
rounding (chc._units) at 0 in every row: a floor of 1e-9 added to the spread was in the
covariate's units, and earnings with a spread of 5,000 dollars, logged in units of 1e13
dollars, reached it at a third of their spread.
The treatment, the outcome and each covariate are read as float64, as a panel's columns are,
where they hold real numbers (chc.frames._real_numbers); the estimator casts them to its
own dtype after. NumPy sums a matrix's columns row by row, so in float32 their means were
rounded more with every row: at a million rows, a covariate of 10,000 give or take 1 reached
the estimator up to 1.7 times its spread off, and at ten million one of 14,000 give or take
9,500 up to 4.4% of its spread.
Raises:
| Type | Description |
|---|---|
ValueError
|
when a covariate is named |
lalonde_report(data, estimators)
¶
Format the experimental truth, the naive bias, and each estimator's adjusted ATE.