Every unit carries two outcomes — the one we see, and the one we don't. Causal inference is the craft of reconstructing that missing twin.
The fundamental problem: for any single unit we observe exactly one of its two potential outcomes. The other is a counterfactual — drawn as a dashed ghost.
The most obvious estimate takes the average outcome of the treated group and subtracts the average of the control group. It feels honest. It is usually wrong, because of selection: the people who end up treated are rarely a random slice. In a job-training program, enrollees tend to be more motivated and would have earned more even without training — so the raw gap mixes the real effect with a head start the groups never shared.
If treated units sit further along a covariate that itself drives the outcome, comparing raw averages compares two different populations.
\(Y\) — the outcome we actually observe for a unit
\(T\) — treatment indicator: \(1\) if treated, \(0\) if control
\(E[Y\mid T{=}1]\) — average observed outcome among the treated; \(E[Y\mid T{=}0]\) among controls
ATT — the real quantity we want: the effect on those actually treated
\(E[Y(0)\mid T{=}1]-E[Y(0)\mid T{=}0]\) — selection bias: how treated and control differ in their untreated outcomes, before any treatment
Everything that follows is machinery for driving that second term to zero.
Remember
The raw gap is the treatment effect only if the groups would have looked identical without treatment. They usually wouldn't.
02 — The core idea
Compare like with like
If the groups differ on background traits, stop comparing them as wholes and instead pair each treated unit with control units that look the same on those traits. Within a pocket of identical-looking units, who got treated is — by assumption — no longer systematic. That assumption is unconfoundedness: once we condition on covariates \(X\), treatment is as good as random.
\(Y(0),Y(1)\) — the two potential outcomes (untreated, treated)
\(\perp\) — "is statistically independent of"
\(X\) — the covariates we measured and condition on
Line 1 — unconfoundedness: holding \(X\) fixed, the potential outcomes are independent of who got treated (no hidden driver of both)
Line 2 — overlap: at every value of \(X\), the chance of treatment is strictly between 0 and 1, so both treated and control units actually exist to compare
For each treated unit, find the closest control in covariate space and use its outcome as a stand-in for the treated unit's missing untreated outcome.
Remember
Matching works only as far as the covariates you matched on capture every trait that drives both treatment and outcome.
03 — The simplest matching
Exact matching, and the ceiling it hits
The cleanest version pairs each treated unit with controls having identical covariate values. With a few discrete covariates — sex, region, an age band — this is perfect: no leftover difference, no bias. It breaks once covariates are continuous or numerous, because no exact twin exists. You accept a near match, and that residual gap is the matching discrepancy where bias re-enters.
The curse of dimensionality: to be close on k covariates at once, a neighbor must fall in a tiny box whose volume collapses, so nearest-neighbor distance grows like N^(−1/k).
This matters because of a rate race. Your estimator's random noise shrinks at \(1/\sqrt{N}\). For matching bias to be harmless it must shrink faster than that — but the discrepancy shrinks only like \(N^{-1/k}\):
\(N\) — sample size; \(k\) — number of continuous covariates matched on
\(k=1\) — gap \(\sim 1/N\), shrinks faster than the noise → harmless
\(k=2\) — gap \(\sim 1/\sqrt N\), same order as the noise → borderline
\(k\ge 3\) — gap shrinks slower than the noise → bias dominates and never washes out
Remember
With two or more continuous covariates, the leftover matching gap shrinks no faster than your sampling noise. That is exactly the hole §04 fills.
04 — Beating dimensionality
Propensity score matching
If many dimensions are the enemy, collapse them into one. The propensity score is a unit's probability of being treated given its covariates. Rosenbaum and Rubin showed it is a balancing score: matching on this single number balances the whole covariate vector in expectation.
Definition, and the balancing property
$$e(x)=P(T{=}1\mid X{=}x)$$ $$\big(Y(0),Y(1)\big)\perp T\mid X \;\Rightarrow\; \big(Y(0),Y(1)\big)\perp T\mid e(X)$$
reading it
\(e(x)\) — the propensity score: the probability of treatment for a unit with covariates \(x\), usually estimated by logistic regression
The implication — if conditioning on the full \(X\) makes treatment ignorable, then conditioning on the single number \(e(X)\) does too
A k-dimensional matching problem becomes 1-dimensional: estimate each unit's treatment probability, then match units with similar scores.
Remember
The propensity score balances what you measured. It fixes dimensionality, never unmeasured confounding.
In one breath
Comparing groups confounds effect with selection. Matching compares like with like — exact when covariates are discrete, only approximate when continuous. The propensity score tames dimensionality by collapsing many covariates into a single treatment probability. Each method drives the selection bias toward zero, but only as far as the covariates you measured capture every trait that drives both treatment and outcome.