Type at least 2 letters. Enter opens the first result, Esc closes.

    Causal Inference · Lesson 5 · Estimating causal effects

    Adjustment, matching, propensity scores and inverse probability weighting

    Intermediate 95 min 5 interactive figures 5 videos Colab notebook

    Before this lesson: potential outcomes, the ATE and ATT, exchangeability and positivity (lesson 02); the backdoor criterion and the adjustment formula (lesson 04); linear regression (probability 13) and logistic regression. Importance sampling (probability 14) helps but is not required. Time: about 95 minutes, plus the notebook.


    Why this matters #

    Most causal questions in industry, medicine and policy are answered without an experiment: users opt in to a feature, doctors choose a drug, workers join a training program. Lesson 04 told us which variables to adjust for. This lesson is about how to adjust with data. The estimators here are the standard tools of epidemiology (Hernán and Robins), economics (Imbens and Rubin) and tech companies (observational studies next to A/B tests). They are also the base of causal machine learning: inverse propensity scoring (IPS) in recommender systems and learning to rank, off-policy evaluation in reinforcement learning (lesson 11), and double machine learning (lesson 08), which is AIPW with ML models.

    1. Predict first #

    2. The picture #

    2.1 The problem: the groups differ before treatment #

    A job-training program is open to everyone. People with low past earnings join more often. Past earnings also predict future earnings. So the people who joined would earn less even without the program, and the naive difference in mean earnings mixes the effect of the program with this difference between the groups. This is confounding by XX = past earnings (lesson 01 and lesson 04).

    If XX blocks every backdoor path from TT to YY, the fix is to compare like with like: treated and control units with the same XX. There are three ways to do this, and this lesson treats all three:

    Idea Method What it models
    predict the missing potential outcome outcome regression (the g-formula) μt(x)=E[Y∣T=t,X=x]\mu_t(x) = \mathbb{E}[Y \mid T = t, X = x]
    find a similar unit of the other group matching a distance between units
    reweight the units so that the groups look alike inverse probability weighting e(x)=P(T=1∣X=x)e(x) = P(T = 1 \mid X = x)

    2.2 Weighting creates a pseudo-population #

    Start with a population of 100 people and one binary confounder XX. Half have X=1X = 1. In the group X=1X = 1, 80% are treated: e(1)=0.8e(1) = 0.8. In the group X=0X = 0, 20% are treated: e(0)=0.2e(0) = 0.2. The outcome is Y=T+2X+εY = T + 2X + \varepsilon, so the true effect is 11 for everyone.

    The treated group is mostly X=1X = 1 (40 of 50 people), and X=1X = 1 adds 2 to YY. So the naive difference is 2.2, not 1:

    E[Y∣T=1]−E[Y∣T=0]=(1+2⋅0.8)−2⋅0.2=2.2.\mathbb{E}[Y \mid T{=}1] - \mathbb{E}[Y \mid T{=}0] = (1 + 2 \cdot 0.8) - 2 \cdot 0.2 = 2.2 .

    Now give each treated unit the weight 1/e(x)1/e(x) and each control unit the weight 1/(1−e(x))1/(1 - e(x)):

    Group 1/e1/e 1/(1−e)1/(1 - e) Treated: count → weighted Control: count → weighted
    X=1X{=}1 1.25 5 40 → 50 10 → 50
    X=0X{=}0 5 1.25 10 → 50 40 → 50

    After weighting, each group stands for the whole population: 50 people with X=1X = 1 and 50 with X=0X = 0. A treated person in the group X=0X = 0 is rare (only 10 of 50), so this person counts 5 times. Together, the 10 treated people of that group now stand for all 50 people of the group, including the 40 who were not treated. Inside each group of XX the treatment was "as good as random", so these stand-ins are fair. In the pseudo-population XX no longer predicts TT, and the weighted difference in means is (1+2⋅0.5)−(2⋅0.5)=1(1 + 2 \cdot 0.5) - (2 \cdot 0.5) = 1: the true effect.

    Interactive figure: loading…

    Switch between the weights. "raw" shows the data: treated units sit at large xx, where YY is high anyway, so the naive difference is too large. "IPW (ATE)" gives each unit the weight 1/e^(x)1/\hat e(x) or 1/(1−e^(x))1/(1 - \hat e(x)); the dot area shows the weight. Notice the large control dots at large xx: rare controls stand for many people. The dashed lines are the weighted group means; their difference is the estimate. In the histograms below, both weighted groups now match the whole sample (dashed outline), and the SMD of xx drops to about 0. "weights for ATT" makes the controls look like the treated group; "IPW, trimmed" drops units with e^\hat e outside [0.1,0.9][0.1, 0.9]. The aqua curves are the true μ0(x)\mu_0(x) and μ1(x)\mu_1(x), and the true effect changes with the target. Move the confounding slider to the right and watch the largest weight and the effective sample size.

    Quick check

    A unit has an estimated propensity score e^(x)=0.9\hat e(x) = 0.9. What is its IPW weight for the ATE if it is treated, and if it is a control?

    2.3 Matching: find a twin in the other group #

    Matching answers the causal question for each treated unit directly. For a treated unit ii we do not observe Yi(0)Y_i(0). We take the control unit j(i)j(i) with the closest covariates and use its outcome Yj(i)Y_{j(i)} as a stand-in for Yi(0)Y_i(0). The average of Yi−Yj(i)Y_i - Y_{j(i)} over the treated units estimates the ATT, the effect for the treated. If the match were perfect (Xj(i)=XiX_{j(i)} = X_i), exchangeability given XX would make Yj(i)Y_{j(i)} a fair stand-in for Yi(0)Y_i(0).

    With one or two covariates good matches are easy to find. With many covariates they are not: in high dimension every unit is far from every other unit (the curse of dimensionality). The propensity score solves this problem: section 3.4 shows that it is enough to match on the one number e(X)e(X).

    Interactive figure: loading…

    Compare the two kinds of matching. Each treated unit is joined to its nearest control (with replacement; faint controls are never used). "covariates X" uses the distance in the plane: pairs are close. "propensity score" uses the distance between e^\hat e values: a treated unit may take a control far away along a dashed line of equal e^\hat e. Both reduce the SMDs and move the matching estimate (black) from the naive difference toward the true ATT. Now make the caliper small: treated units with no close control are dropped (hollow), the estimate concerns the remaining treated units only, and its truth changes too. (The caliper is in standard deviations: of xx for covariate matching, of logit⁡e^\operatorname{logit}\hat e for propensity matching.)

    Quick check

    You match every treated unit to its nearest control and average the differences Yi−Yj(i)Y_i - Y_{j(i)}. Which causal quantity does this estimate?

    3. Definitions and main results #

    3.1 Assumptions and identification #

    We observe nn independent copies of (X,T,Y)(X, T, Y), where XX is a vector of pre-treatment covariates: measured before TT and not affected by TT. We write μt(x)=E[Y∣T=t,X=x]\mu_t(x) = \mathbb{E}[Y \mid T = t, X = x] for the outcome regressions and e(x)=P(T=1∣X=x)e(x) = P(T = 1 \mid X = x) for the propensity score. Three assumptions (lesson 02):

    1. Consistency. If Ti=tT_i = t, then Yi=Yi(t)Y_i = Y_i(t). (This includes "no interference": the outcome of unit ii does not depend on the treatment of other units.)
    2. Conditional exchangeability (also called no unmeasured confounding, ignorability or unconfoundedness): (Y(0),Y(1))⊥ ⁣ ⁣ ⁣⊥T∣X(Y(0), Y(1)) \perp\!\!\!\perp T \mid X. Within each level of XX, the treatment is as good as random. In graph language: XX satisfies the backdoor criterion of lesson 04.
    3. Positivity (also called overlap): 0<e(x)<10 < e(x) < 1 for every xx with p(x)>0p(x) > 0. Every kind of unit has some chance of being treated and some chance of being a control.

    Which ones can the data check? Positivity can be checked, at least roughly: look at the estimated e^(x)\hat e(x) (section 3.6). Conditional exchangeability cannot be checked: it is a statement about Y(0)Y(0) of the treated units, and we never see it. It comes from knowledge of the problem (a causal graph), not from the data. Section 3.9 asks what happens if it fails.

    Theorem (g-formula, or standardization). Under the three assumptions,

    E[Y(t)]=E[μt(X)](t=0,1),τATE=E[μ1(X)−μ0(X)].\mathbb{E}[Y(t)] = \mathbb{E}\big[\mu_t(X)\big] \quad (t = 0, 1), \qquad \tau_{\mathrm{ATE}} = \mathbb{E}\big[\mu_1(X) - \mu_0(X)\big].

    Proof (for t=1t = 1; the case t=0t = 0 is the same).

    1. By the law of total expectation, E[Y(1)]=E[E[Y(1)∣X]]\mathbb{E}[Y(1)] = \mathbb{E}\big[\mathbb{E}[Y(1) \mid X]\big].
    2. By conditional exchangeability, Y(1)Y(1) is independent of TT given XX, so E[Y(1)∣X]=E[Y(1)∣T=1,X]\mathbb{E}[Y(1) \mid X] = \mathbb{E}[Y(1) \mid T = 1, X]. Positivity (e(X)>0e(X) > 0) makes sure that this conditional expectation is defined for every XX.
    3. By consistency, Y=Y(1)Y = Y(1) when T=1T = 1, so E[Y(1)∣T=1,X]=E[Y∣T=1,X]=μ1(X)\mathbb{E}[Y(1) \mid T = 1, X] = \mathbb{E}[Y \mid T = 1, X] = \mu_1(X). ■\blacksquare

    The right-hand side contains only observable quantities. So the ATE is identified: it is a property of the distribution of (X,T,Y)(X, T, Y). This is the adjustment formula of lesson 04, written with expectations. For the treated, the same steps give τATT=E[Y∣T=1]−E[μ0(X)∣T=1]\tau_{\mathrm{ATT}} = \mathbb{E}[Y \mid T = 1] - \mathbb{E}[\mu_0(X) \mid T = 1]. The ATT needs less: exchangeability only for Y(0)Y(0), and positivity only in the form e(x)<1e(x) < 1.

    Every method below estimates the same estimand E[μ1(X)−μ0(X)]\mathbb{E}[\mu_1(X) - \mu_0(X)] (or its ATT version). They differ in what they model and in how they fail.

    3.2 Outcome regression (standardization) #

    Estimator. Fit μ^1\hat\mu_1 on the treated units and μ^0\hat\mu_0 on the controls (any regression or ML model). Then predict both potential outcomes for every unit and average:

    τ^reg=1n∑i=1n[μ^1(Xi)−μ^0(Xi)].\hat\tau_{\mathrm{reg}} = \frac{1}{n}\sum_{i=1}^{n} \big[\hat\mu_1(X_i) - \hat\mu_0(X_i)\big].

    For the ATT, average only over the treated units. This is the plug-in version of the g-formula.

    The usual regression is a special case. Fit one linear model Y=α+τT+β⊤X+εY = \alpha + \tau T + \beta^\top X + \varepsilon and report τ^\hat\tau. This equals τ^reg\hat\tau_{\mathrm{reg}} when the model is right: μ1\mu_1 and μ0\mu_0 are linear and parallel (a constant effect). When the effect differs between units, the coefficient τ^\hat\tau is not the ATE in general. For a discrete XX with one dummy per level, it is a weighted average of the effects τ(x)\tau(x) with weights proportional to P(X=x) e(x)(1−e(x))P(X = x)\, e(x)(1 - e(x)) (Angrist 1998). Example: two equal groups with e=0.5,0.9e = 0.5, 0.9 and effects τ=4,2\tau = 4, 2. The ATE is 33 and the ATT is 2.712.71, but the weights are 0.250.25 and 0.090.09, so the coefficient is (0.25⋅4+0.09⋅2)/0.34=3.47(0.25 \cdot 4 + 0.09 \cdot 2)/0.34 = 3.47: neither the ATE nor the ATT.

    Weak point: extrapolation. Where there are almost no controls (say, at large xx in the figure of section 2.2), μ^0\hat\mu_0 is a guess made from other regions. A linear model extrapolates without a warning. Regression hides poor overlap; matching and weighting show it.

    3.3 Matching #

    • Exact matching. Pair units with exactly the same XX. Possible only with few discrete covariates. If each treated unit is compared with the mean of all controls with the same XX, the matching estimate equals the plug-in g-formula for the ATT.
    • Nearest-neighbor matching (with replacement). For each treated unit ii, find the control j(i)j(i) that minimizes a distance d(Xi,Xj)d(X_i, X_j): Euclidean on standardized covariates, Mahalanobis, or ∣logit⁡e^(Xi)−logit⁡e^(Xj)∣|\operatorname{logit} \hat e(X_i) - \operatorname{logit} \hat e(X_j)|. Then
    τ^ATT=1n1∑i:Ti=1(Yi−Yj(i)).\hat\tau_{\mathrm{ATT}} = \frac{1}{n_1}\sum_{i : T_i = 1} \big(Y_i - Y_{j(i)}\big).
    • kk matches. Average the outcomes of the kk nearest controls: lower variance, larger bias.
    • Caliper. Drop a treated unit when its best match is farther than a caliper cc. A common choice is c=0.2c = 0.2 standard deviations of logit⁡e^\operatorname{logit} \hat e (Austin 2011). The dropped units change the estimand: we now estimate the effect for the treated units that have a match.

    Matching estimates the ATT naturally. Its strength is transparency: you can look at the pairs. Its weakness is bias from imperfect matches. If Xj(i)≠XiX_{j(i)} \ne X_i, the stand-in has the wrong expected outcome: E[Yj(i)]=μ0(Xj(i))≠μ0(Xi)\mathbb{E}[Y_{j(i)}] = \mu_0(X_{j(i)}) \ne \mu_0(X_i).

    Matching bias and how to remove it (Abadie and Imbens)

    With kk continuous covariates, the distance to the nearest control shrinks like n−1/kn^{-1/k}, so the bias of nearest-neighbor matching also shrinks like n−1/kn^{-1/k} (Abadie and Imbens 2006). The standard error shrinks like n−1/2n^{-1/2}. For k≥3k \ge 3 the bias shrinks more slowly than the noise, so in large samples it dominates and confidence intervals become wrong. The bias-corrected matching estimator (Abadie and Imbens 2011) fixes this. It fits a regression μ^0\hat\mu_0 on the controls and replaces Yj(i)Y_{j(i)} by Yj(i)+μ^0(Xi)−μ^0(Xj(i))Y_{j(i)} + \hat\mu_0(X_i) - \hat\mu_0(X_{j(i)}): the regression moves the stand-in from Xj(i)X_{j(i)} to XiX_i. A second warning: the standard bootstrap is not valid for nearest-neighbor matching with a fixed number of matches (Abadie and Imbens 2008); use their analytic variance formula or a weighting estimator instead.

    3.4 The propensity score #

    Definition. The propensity score is e(x)=P(T=1∣X=x)e(x) = P(T = 1 \mid X = x) (Rosenbaum and Rubin 1983). It compresses a whole vector XX into one number between 0 and 1.

    Theorem (balancing property). (a) T⊥ ⁣ ⁣ ⁣⊥X∣e(X)T \perp\!\!\!\perp X \mid e(X): units with the same propensity score have the same distribution of XX in the treated and in the control group. (b) If (Y(0),Y(1))⊥ ⁣ ⁣ ⁣⊥T∣X(Y(0), Y(1)) \perp\!\!\!\perp T \mid X, then (Y(0),Y(1))⊥ ⁣ ⁣ ⁣⊥T∣e(X)(Y(0), Y(1)) \perp\!\!\!\perp T \mid e(X).

    So conditioning on the single number e(X)e(X) is as good as conditioning on all of XX. We can match, stratify or weight on e(X)e(X) instead of XX.

    Proof of the balancing theorem

    For a binary TT, independence of TT and AA given BB means P(T=1∣A,B)=P(T=1∣B)P(T = 1 \mid A, B) = P(T = 1 \mid B).

    (a)

    1. e(X)e(X) is a function of XX, so P(T=1∣X,e(X))=P(T=1∣X)=e(X)P(T = 1 \mid X, e(X)) = P(T = 1 \mid X) = e(X).
    2. By the tower rule, P(T=1∣e(X))=E[P(T=1∣X)∣e(X)]=E[e(X)∣e(X)]=e(X)P(T = 1 \mid e(X)) = \mathbb{E}\big[P(T = 1 \mid X) \mid e(X)\big] = \mathbb{E}[e(X) \mid e(X)] = e(X).
    3. Steps 1 and 2 give the same value, so P(T=1∣X,e(X))=P(T=1∣e(X))P(T = 1 \mid X, e(X)) = P(T = 1 \mid e(X)): T⊥ ⁣ ⁣ ⁣⊥X∣e(X)T \perp\!\!\!\perp X \mid e(X).

    (b) Write Y(⋅)=(Y(0),Y(1))Y(\cdot) = (Y(0), Y(1)).

    1. By the tower rule, P(T=1∣Y(⋅),e(X))=E[P(T=1∣Y(⋅),X)∣Y(⋅),e(X)]P(T = 1 \mid Y(\cdot), e(X)) = \mathbb{E}\big[P(T = 1 \mid Y(\cdot), X) \mid Y(\cdot), e(X)\big].
    2. By exchangeability given XX, P(T=1∣Y(⋅),X)=P(T=1∣X)=e(X)P(T = 1 \mid Y(\cdot), X) = P(T = 1 \mid X) = e(X).
    3. So P(T=1∣Y(⋅),e(X))=E[e(X)∣Y(⋅),e(X)]=e(X)=P(T=1∣e(X))P(T = 1 \mid Y(\cdot), e(X)) = \mathbb{E}[e(X) \mid Y(\cdot), e(X)] = e(X) = P(T = 1 \mid e(X)) (the last step is step 2 of part (a)). ■\blacksquare

    Estimating e(x)e(x). In practice ee is unknown. Fit a probabilistic classifier of TT on XX: logistic regression, or a boosted model with calibrated probabilities. The probabilities must be calibrated, because IPW divides by them.

    Judge the propensity model by balance, not by accuracy. The goal is not to predict TT well. The goal is that, after matching or weighting on e^\hat e, the covariates are balanced (section 3.7). A very accurate model is bad news: if XX predicts TT almost perfectly, then the treated and control units live in different regions of XX, and there is little overlap to compare. Also, do not add variables only because they predict TT: a variable that affects TT but not YY (an instrument, lesson 04) adds variance and can amplify bias.

    Quick check

    Your propensity model has AUC 0.99 on held-out data. What does this tell you about the causal analysis?

    3.5 Inverse probability weighting #

    The Horvitz–Thompson IPW estimator of the ATE is

    τ^IPW=1n∑i=1n[TiYie^(Xi)−(1−Ti) Yi1−e^(Xi)].\hat\tau_{\mathrm{IPW}} = \frac{1}{n}\sum_{i=1}^{n}\left[\frac{T_i Y_i}{\hat e(X_i)} - \frac{(1 - T_i)\,Y_i}{1 - \hat e(X_i)}\right].

    Theorem. Under the three assumptions, with the true ee: E[TYe(X)]=E[Y(1)]\mathbb{E}\big[\tfrac{TY}{e(X)}\big] = \mathbb{E}[Y(1)] and E[(1−T)Y1−e(X)]=E[Y(0)]\mathbb{E}\big[\tfrac{(1 - T)Y}{1 - e(X)}\big] = \mathbb{E}[Y(0)]. So τ^IPW\hat\tau_{\mathrm{IPW}} with the true ee is unbiased for τATE\tau_{\mathrm{ATE}}.

    Proof (treated part).

    1. By consistency, TY=T Y(1)TY = T\,Y(1) (when T=0T = 0 both sides are 0).
    2. Condition on XX: E[T Y(1)e(X)]=E[E[T Y(1)∣X]e(X)]\mathbb{E}\big[\tfrac{T\,Y(1)}{e(X)}\big] = \mathbb{E}\Big[\tfrac{\mathbb{E}[T\,Y(1) \mid X]}{e(X)}\Big]. Positivity makes the division safe.
    3. By conditional exchangeability, TT and Y(1)Y(1) are independent given XX. So E[T Y(1)∣X]=E[T∣X] E[Y(1)∣X]\mathbb{E}[T\,Y(1) \mid X] = \mathbb{E}[T \mid X]\,\mathbb{E}[Y(1) \mid X], and this is e(X) E[Y(1)∣X]e(X)\,\mathbb{E}[Y(1) \mid X].
    4. The e(X)e(X) cancels: E[E[Y(1)∣X]]=E[Y(1)]\mathbb{E}\big[\mathbb{E}[Y(1) \mid X]\big] = \mathbb{E}[Y(1)]. ■\blacksquare

    IPW is importance sampling. We want averages over the whole population, but the treated units are a sample from p(x∣T=1)p(x \mid T = 1), not from p(x)p(x). By Bayes' rule p(x)/p(x∣T=1)=P(T=1)/e(x)p(x)/p(x \mid T = 1) = P(T = 1)/e(x): the weight 1/e(x)1/e(x) is the importance weight, up to a constant (probability 14).

    The normalized (Hájek) estimator. The weights Ti/e^iT_i/\hat e_i sum to nn only on average. Dividing by their actual sum gives a weighted difference in means:

    τ^Hajek=∑iTiYi/e^i∑iTi/e^i−∑i(1−Ti)Yi/(1−e^i)∑i(1−Ti)/(1−e^i).\hat\tau_{\mathrm{Hajek}} = \frac{\sum_i T_i Y_i / \hat e_i}{\sum_i T_i / \hat e_i} - \frac{\sum_i (1 - T_i) Y_i / (1 - \hat e_i)}{\sum_i (1 - T_i)/(1 - \hat e_i)}.

    It has a small bias but usually a much smaller variance, and it does not change when you add a constant to YY (the Horvitz–Thompson form does). Use it by default.

    Weights for the ATT. Treated units get weight 1. Control units get e^(x)/(1−e^(x))\hat e(x)/(1 - \hat e(x)), the odds of treatment. This reweights the controls to look like the treated group, so the weighted control mean estimates E[Y(0)∣T=1]\mathbb{E}[Y(0) \mid T = 1]. (Check: p(x∣T=1)/p(x∣T=0)=e(x)1−e(x)⋅P(T=0)P(T=1)p(x \mid T = 1)/p(x \mid T = 0) = \frac{e(x)}{1 - e(x)} \cdot \frac{P(T = 0)}{P(T = 1)}.)

    Estimated or true ee? The proof uses the true ee. In practice we plug in e^\hat e. A surprising fact: with a good estimate (a correct parametric model, or a flexible model that grows with nn), IPW with e^\hat e has a variance at least as small as IPW with the true ee, and with a flexible model it reaches the smallest possible variance (Hirano, Imbens and Ridder 2003). The estimated weights also correct the chance imbalance of XX in the sample.

    3.6 Overlap and extreme weights #

    If e(x)e(x) is close to 0 or 1 for some units, their weights are huge, and a few units decide the estimate. The variance of IPW grows without bound as e→0e \to 0 or 11. Two numbers make this visible:

    • the largest weight, and
    • the effective sample size (Kish) of a group with weights wiw_i: ESS=(∑iwi)2/∑iwi2\mathrm{ESS} = \big(\sum_i w_i\big)^2 / \sum_i w_i^2. Equal weights give ESS=n\mathrm{ESS} = n; one dominant weight gives about 1. Example: weights (1,1,1,1,6)(1, 1, 1, 1, 6) give 102/40=2.510^2/40 = 2.5, not 5.

    Remedies, and their price.

    • Trimming: keep only units with α≤e^≤1−α\alpha \le \hat e \le 1 - \alpha (often α=0.1\alpha = 0.1, Crump et al. 2009). The variance falls, but the estimand changes: it is now the effect for the units with good overlap, not the ATE. Say so when you report it.
    • Truncating (or clipping) weights at a maximum value: keeps all units, adds bias.
    • Overlap weights (Li, Morgan and Zaslavsky 2018): treated units get 1−e^1 - \hat e and controls get e^\hat e. They target the effect in the population with the most overlap, E[e(X)(1−e(X))τ(X)]/E[e(X)(1−e(X))]\mathbb{E}[e(X)(1 - e(X))\tau(X)]/\mathbb{E}[e(X)(1 - e(X))], and never explode.

    Poor overlap is a property of the data, not of the estimator. Outcome regression hides it by extrapolating, and AIPW (section 3.8) also divides by e^\hat e: it reduces the damage but does not remove it. When overlap is poor, the honest answer is often an effect for a smaller population.

    Interactive figure: loading…

    Increase the confounding strength and watch the histograms of e^\hat e: the treated units (above the axis) move to the right, the controls (below) to the left, and the overlap in the middle shrinks. The largest weight grows and the effective sample sizes fall. Press Run 200 samples to repeat the study 200 times: the estimates without trimming spread widely around the true ATE of 1. Now raise the trimming α\alpha: the grey zones are removed, the spread falls, and the true target of the trimmed estimate moves below 1, because the units with the largest effects were trimmed away.

    3.7 Diagnostics: balance and overlap #

    Before you report an effect, check the two things the data can check.

    Overlap. Plot the histograms of e^\hat e for the treated and the control group (as in the figure above). Look for regions where one group has no units. Report the largest weight and the ESS.

    Balance. For each covariate, compute the standardized mean difference

    SMD=xˉ1−xˉ0(s12+s02)/2,\mathrm{SMD} = \frac{\bar x_1 - \bar x_0}{\sqrt{(s_1^2 + s_0^2)/2}},

    where xˉt\bar x_t and st2s_t^2 are the mean and variance in group tt. For a binary covariate with shares p1,p0p_1, p_0, use st2=pt(1−pt)s_t^2 = p_t(1 - p_t). After weighting or matching, recompute the means with the weights (or in the matched sample) and keep the denominator from the raw data. A common rule is ∣SMD∣<0.1|\mathrm{SMD}| < 0.1 for every covariate (Austin 2011). Unlike a tt-test, the SMD does not depend on the sample size. Papers show the means before and after adjustment in a "Table 1" and the SMDs in a "Love plot".

    What diagnostics cannot do. Good balance on the measured XX says nothing about an unmeasured confounder UU. Balance checks the estimation step (did the weights or matches do their job?), not the identification step (is XX enough?).

    Quick check

    After weighting, all covariates have ∣SMD∣<0.05|\mathrm{SMD}| < 0.05 and the propensity histograms overlap well. Which statement is correct?

    3.8 Doubly robust estimation (AIPW) #

    Regression needs a correct outcome model. IPW needs a correct propensity model. The augmented inverse probability weighting (AIPW) estimator (Robins, Rotnitzky and Zhao 1994) uses both:

    τ^AIPW=1n∑i=1n[ μ^1(Xi)−μ^0(Xi)+Ti (Yi−μ^1(Xi))e^(Xi)−(1−Ti) (Yi−μ^0(Xi))1−e^(Xi)].\begin{aligned} \hat\tau_{\mathrm{AIPW}} = \frac{1}{n}\sum_{i=1}^{n}\Big[\,&\hat\mu_1(X_i) - \hat\mu_0(X_i) \\ &+ \frac{T_i\,(Y_i - \hat\mu_1(X_i))}{\hat e(X_i)} \\ &- \frac{(1 - T_i)\,(Y_i - \hat\mu_0(X_i))}{1 - \hat e(X_i)}\Big]. \end{aligned}

    Read it as "regression estimate + a weighted average of the regression's mistakes". If the outcome model is right, the residuals average to zero and the correction does nothing on average. If the outcome model is wrong but the weights are right, the weighted residuals measure the mistake and remove it.

    Theorem (double robustness). Let μ~t\tilde\mu_t and e~\tilde e be the limits of the fitted models. Under the three assumptions, AIPW is consistent for the ATE if either μ~0=μ0\tilde\mu_0 = \mu_0 and μ~1=μ1\tilde\mu_1 = \mu_1, or e~=e\tilde e = e. It does not need both.

    Proof of double robustness

    Take the treated part, ψ1=μ~1(X)+T (Y−μ~1(X))/e~(X)\psi_1 = \tilde\mu_1(X) + T\,(Y - \tilde\mu_1(X))/\tilde e(X); the control part is the same with 1−T1 - T and 1−e~1 - \tilde e.

    1. By consistency, T Y=T Y(1)T\,Y = T\,Y(1), so ψ1=μ~1(X)+T (Y(1)−μ~1(X))/e~(X)\psi_1 = \tilde\mu_1(X) + T\,(Y(1) - \tilde\mu_1(X))/\tilde e(X).
    2. Condition on XX. By conditional exchangeability, E[T (Y(1)−μ~1(X))∣X]=e(X) (μ1(X)−μ~1(X))\mathbb{E}[T\,(Y(1) - \tilde\mu_1(X)) \mid X] = e(X)\,(\mu_1(X) - \tilde\mu_1(X)), using E[Y(1)∣X]=μ1(X)\mathbb{E}[Y(1) \mid X] = \mu_1(X) (section 3.1).
    3. So E[ψ1]=E[μ~1(X)+e(X)e~(X)(μ1(X)−μ~1(X))]\mathbb{E}[\psi_1] = \mathbb{E}\Big[\tilde\mu_1(X) + \frac{e(X)}{\tilde e(X)}\big(\mu_1(X) - \tilde\mu_1(X)\big)\Big].
    4. Subtract E[Y(1)]=E[μ1(X)]\mathbb{E}[Y(1)] = \mathbb{E}[\mu_1(X)]:
    E[ψ1]−E[Y(1)]=E[(μ1(X)−μ~1(X)) e(X)−e~(X)e~(X)].\mathbb{E}[\psi_1] - \mathbb{E}[Y(1)] = \mathbb{E}\left[\big(\mu_1(X) - \tilde\mu_1(X)\big)\,\frac{e(X) - \tilde e(X)}{\tilde e(X)}\right].
    1. The bias is an average of a product of two errors. It is zero if μ~1=μ1\tilde\mu_1 = \mu_1 (first factor zero) or if e~=e\tilde e = e (second factor zero). The sample average converges to this expectation by the law of large numbers. ■\blacksquare

    Two more facts. When both models are correct, AIPW has the smallest possible asymptotic variance among regular estimators that use only these assumptions (it reaches the semiparametric efficiency bound). And the product form of the bias in step 4 is the key to lesson 08: with flexible ML models and cross-fitting (fit the models on one part of the data, evaluate the formula on the other part), two slowly converging models still give a fast-converging estimate. This is double machine learning.

    Interactive figure: loading…

    Make one model wrong at a time. "wrong" models use x2x_2 instead of x22x_2^2, so they miss the confounding through x22x_2^2. Each run simulates 200 studies with 500 units. With a wrong propensity model, IPW moves away from the true ATE of 2, but AIPW stays centered on it. With a wrong outcome model, regression is off but AIPW is still centered. With both models wrong, AIPW fails too (the mean dot turns magenta). Notice also the spread: IPW with correct weights is unbiased but noisier than regression and AIPW.

    Quick check

    In a study, the outcome model of AIPW is misspecified (it misses a nonlinear term), but the propensity model is correct. What happens as nn grows?

    3.9 Sensitivity analysis: what if a confounder is missing? #

    Every method above assumes conditional exchangeability. A sensitivity analysis asks: how strong would an unmeasured confounder UU have to be to change the conclusion? A result is credible only together with this statement.

    Omitted-variable bias (linear case). Suppose the true model is Y=τT+β⊤X+γU+εY = \tau T + \beta^\top X + \gamma U + \varepsilon, but we regress YY on TT and XX only. Then the estimate shifts by

    τ^without U−τ^with U=γ^ δ^,\hat\tau_{\text{without } U} - \hat\tau_{\text{with } U} = \hat\gamma\,\hat\delta,

    where γ^\hat\gamma is the coefficient of UU in the full regression and δ^\hat\delta is the coefficient of TT in the regression of UU on TT and XX (this is an exact identity of least squares). The bias is large only if UU is related to both the outcome (γ\gamma) and the treatment (δ\delta).

    The same idea with partial R2R^2 (Cinelli and Hazlett 2020). Measure the strength of UU by two numbers between 0 and 1: RT∼U∣X2R^2_{T \sim U \mid X}, the share of the variance of TT (after XX) that UU explains, and RY∼U∣T,X2R^2_{Y \sim U \mid T, X}, the same for YY. Then

    ∣bias∣=se(τ^) df RY∼U∣T,X2  RT∼U∣X21−RT∼U∣X2,|\text{bias}| = \mathrm{se}(\hat\tau)\,\sqrt{\mathrm{df}}\,\sqrt{\frac{R^2_{Y \sim U \mid T, X}\;R^2_{T \sim U \mid X}}{1 - R^2_{T \sim U \mid X}}},

    where df\mathrm{df} is the residual degrees of freedom of the regression. The robustness value RV\mathrm{RV} is the common value of the two partial R2R^2 that would bring the estimate to 0: RV=12(f4+4f2−f2)\mathrm{RV} = \tfrac12\big(\sqrt{f^4 + 4f^2} - f^2\big) with f=∣τ^∣/(sedf)f = |\hat\tau|/(\mathrm{se}\sqrt{\mathrm{df}}). To judge whether such a UU is plausible, compare it with the observed covariates: "a confounder as strong as past earnings".

    The E-value (VanderWeele and Ding 2017) does the same on the risk-ratio scale, for a binary outcome. A confounder with risk ratio RRTU\mathrm{RR}_{TU} with the treatment and RRUY\mathrm{RR}_{UY} with the outcome can change an observed risk ratio by at most the bias factor (Ding and VanderWeele 2016)

    B=RRTU RRUYRRTU+RRUY−1.B = \frac{\mathrm{RR}_{TU}\,\mathrm{RR}_{UY}}{\mathrm{RR}_{TU} + \mathrm{RR}_{UY} - 1}.

    The E-value is the smallest strength, equal on both sides, that could fully explain away an observed RR>1\mathrm{RR} > 1:

    E=RR+RR (RR−1).E = \mathrm{RR} + \sqrt{\mathrm{RR}\,(\mathrm{RR} - 1)}.

    For RR=2\mathrm{RR} = 2, E=2+2=3.41E = 2 + \sqrt 2 = 3.41: only a confounder that raises both the chance of treatment and the risk of the outcome by a factor of 3.41 could explain the result away. For a protective effect (RR<1\mathrm{RR} < 1), use 1/RR1/\mathrm{RR}. Report the E-value of the confidence limit closest to 1, too.

    Rosenbaum's Γ\Gamma (for matched pairs): assume that two units with the same XX can differ in their odds of treatment by at most a factor Γ\Gamma because of UU. Report the largest Γ\Gamma at which the result is still significant. Γ=1\Gamma = 1 is "no hidden bias".

    Interactive figure: loading…

    Drag the black point to choose the strength of a hypothetical confounder UU; the readout shows the estimate we would get if we could adjust for it. The study is the simulated job-training study of section 4 (estimate 1.321.32, standard error 0.1540.154). The grey lines are contours of the adjusted estimate; the magenta line is where it reaches 0, and the circle on the diagonal is the robustness value. The violet points are confounders exactly as strong as each observed covariate: a hidden confounder as strong as "earnings 1975" would almost remove the effect. Switch to "risk ratios" for the E-value version.

    Answers to section 1. (1) Smaller. A treated person in that group gets 1/0.8=1.251/0.8 = 1.25 and an untreated person gets 1/0.2=51/0.2 = 5: the untreated person's weight is 4 times larger, because untreated people are rare there. (2) Bad news. Near-perfect separation means poor overlap: extreme weights, poor matches, and an estimate that depends on extrapolation. (3) Yes. AIPW is doubly robust: a correct propensity model is enough for consistency.

    4. Worked example #

    (a) Twelve trainees, by hand #

    Twelve people could join a training program. X=1X = 1 means "unemployed last year", T=1T = 1 means "joined", and YY is earnings next year in thousand dollars. Unemployed people join more often (4 of 6) than employed people (2 of 6).

    XX TT YY XX TT YY
    1 1 6, 7, 8, 7 0 1 14, 16
    1 0 4, 6 0 0 10, 12, 11, 11

    Step 1: cell means. μ^1(1)=28/4=7\hat\mu_1(1) = 28/4 = 7, μ^0(1)=10/2=5\hat\mu_0(1) = 10/2 = 5, μ^1(0)=30/2=15\hat\mu_1(0) = 30/2 = 15, μ^0(0)=44/4=11\hat\mu_0(0) = 44/4 = 11. The effect is 7−5=27 - 5 = 2 for the unemployed and 15−11=415 - 11 = 4 for the employed.

    Step 2: naive difference. Treated mean =(28+30)/6=9.67= (28 + 30)/6 = 9.67; control mean =(10+44)/6=9.00= (10 + 44)/6 = 9.00; naive =0.67= 0.67. It is far too small: the treated are mostly unemployed, who earn less anyway.

    Step 3: g-formula. P(X=1)=P(X=0)=6/12P(X = 1) = P(X = 0) = 6/12, so τ^ATE=12⋅2+12⋅4=3\hat\tau_{\mathrm{ATE}} = \tfrac12 \cdot 2 + \tfrac12 \cdot 4 = 3. For the ATT, average over the treated: 4 of them have X=1X = 1 and 2 have X=0X = 0, so τ^ATT=(4⋅2+2⋅4)/6=2.67\hat\tau_{\mathrm{ATT}} = (4 \cdot 2 + 2 \cdot 4)/6 = 2.67.

    Step 4: exact matching (ATT). Match each treated unit with the mean of the controls in its cell (5 or 11). This gives the same 2.67 as step 3:

    τ^ATT=(28−4⋅5)+(30−2⋅11)6=2.67.\hat\tau_{\mathrm{ATT}} = \frac{(28 - 4 \cdot 5) + (30 - 2 \cdot 11)}{6} = 2.67 .

    Step 5: propensity scores and IPW weights. e^(1)=4/6=2/3\hat e(1) = 4/6 = 2/3 and e^(0)=2/6=1/3\hat e(0) = 2/6 = 1/3.

    Cell 1/e^1/\hat e (treated) 1/(1−e^)1/(1 - \hat e) (control) Weighted treated Weighted control
    X=1X{=}1 1.5 3 4⋅1.5=64 \cdot 1.5 = 6 2⋅3=62 \cdot 3 = 6
    X=0X{=}0 3 1.5 2⋅3=62 \cdot 3 = 6 4⋅1.5=64 \cdot 1.5 = 6

    Both weighted groups now have 6 people of each kind, like the whole sample. Weighted means: treated (1.5⋅28+3⋅30)/12=132/12=11(1.5 \cdot 28 + 3 \cdot 30)/12 = 132/12 = 11, control (3⋅10+1.5⋅44)/12=96/12=8(3 \cdot 10 + 1.5 \cdot 44)/12 = 96/12 = 8. So τ^IPW=11−8=3\hat\tau_{\mathrm{IPW}} = 11 - 8 = 3. (Here the weights of each group sum to exactly n=12n = 12, so the Horvitz–Thompson and Hájek forms agree.)

    Step 6: ATT weights. Controls get e^/(1−e^)\hat e/(1 - \hat e): 22 in the cell X=1X = 1, 0.50.5 in the cell X=0X = 0. The weighted control mean is (2⋅10+0.5⋅44)/6=42/6=7(2 \cdot 10 + 0.5 \cdot 44)/6 = 42/6 = 7 (the weights sum to 2⋅2+0.5⋅4=62 \cdot 2 + 0.5 \cdot 4 = 6). So τ^ATT=9.67−7=2.67\hat\tau_{\mathrm{ATT}} = 9.67 - 7 = 2.67.

    Step 7: balance. The share of X=1X = 1 is p1=0.667p_1 = 0.667 among the treated and p0=0.333p_0 = 0.333 among the controls. Both variances are p(1−p)=0.222p(1 - p) = 0.222, so SMD=0.333/0.222=0.71\mathrm{SMD} = 0.333/\sqrt{0.222} = 0.71: strong imbalance. After IPW, both weighted shares are 6/12=0.56/12 = 0.5, so the SMD is 00.

    Step 8: effective sample size of the weighted treated group. Weights (1.5,1.5,1.5,1.5,3,3)(1.5, 1.5, 1.5, 1.5, 3, 3): ESS=122/(4⋅2.25+2⋅9)=144/27=5.33\mathrm{ESS} = 12^2/(4 \cdot 2.25 + 2 \cdot 9) = 144/27 = 5.33 out of 6.

    Step 9: AIPW. With one mean per cell, the residuals Yi−μ^Ti(Xi)Y_i - \hat\mu_{T_i}(X_i) add up to 0 in each cell, so the correction term is 0 and AIPW gives 33 as well. With a saturated discrete XX, all the estimators agree; they differ when XX is continuous or high-dimensional and the models must smooth.

    (b) A simulated job-training study #

    In 1986 LaLonde compared observational estimates of a job-training program with the result of a randomized experiment, and many of them were far off; Dehejia and Wahba (1999) later showed that propensity-score methods on the right covariates came close. The study below is simulated in that spirit, so we know the truth. There are n=2000n = 2000 people with four covariates (age, years of education, earnings in 1975, unemployed in 1975). People with low past earnings join more often. The program raises earnings by 1 (thousand dollars) for people with a job in 1975 and by 2.5 for the unemployed, so the true ATE is about 1.45 and the true ATT, about 1.76, is larger (the unemployed join more often). The code is in section 5.

    Method Target Seed 0 Mean of 200 SD of 200
    naive difference none −3.12-3.12 −2.49-2.49 0.240.24
    OLS coefficient of TT ATE* 1.321.32 1.421.42 0.160.16
    g-formula ATE 1.301.30 1.451.45 0.160.16
    NN matching ATT 1.621.62 1.671.67 0.220.22
    IPW (Hájek) ATE 0.990.99 1.431.43 0.320.32
    IPW, ATT weights ATT 1.721.72 1.731.73 0.210.21
    AIPW ATE 1.281.28 1.451.45 0.170.17

    Truth: ATE =1.45= 1.45 (in seed 0 and on average); ATT =1.76= 1.76 in seed 0 and 1.741.74 on average. "Seed 0" is one study; "mean" and "SD" are over 200 simulated studies. *The OLS coefficient is the ATE only if the effect were the same for everyone. The g-formula uses linear μ^t\hat\mu_t in each arm.

    What to read from the table:

    • The naive difference has the wrong sign. The participants are the people who would earn less anyway.
    • All adjusted methods are close to their targets on average, but one study can be off by one or two standard deviations (IPW gives 0.990.99 in this study). Always report a standard error, for example by the bootstrap (probability 12).
    • IPW for the ATE has the largest spread: some controls with high past earnings are very unlikely to join (e^\hat e as low as 0.007), and the few treated units that look like them get huge weights. The ATT weights do not have this problem: they give such controls a small weight e^/(1−e^)\hat e/(1 - \hat e).
    • Matching is a little biased (1.67 vs 1.74): with four covariates the matches are not exact.
    • AIPW is centered on the truth with about the spread of regression.

    5. In code #

    The code checks the hand computation of part (a) and runs the simulated study of part (b).

    import numpy as np
    from sklearn.linear_model import LinearRegression, LogisticRegression
    from sklearn.neighbors import NearestNeighbors
    
    # (a) the twelve trainees of section 4: X = unemployed last year, T = joined, Y = earnings
    X = np.array([1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])
    T = np.array([1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0])
    Y = np.array([6, 7, 8, 7, 4, 6, 14, 16, 10, 12, 11, 11.])
    e = np.array([T[X == x].mean() for x in X])          # ê(x) = share treated in the cell
    mu = {(t, x): Y[(T == t) & (X == x)].mean() for t in (0, 1) for x in (0, 1)}
    m1, m0 = np.array([mu[1, x] for x in X]), np.array([mu[0, x] for x in X])
    print("naive", round(Y[T == 1].mean() - Y[T == 0].mean(), 2))               # 0.67
    print("g-formula", np.mean(m1 - m0))                                         # 3.0
    print("IPW (HT)", np.mean(T * Y / e - (1 - T) * Y / (1 - e)))                # 3.0
    w = (1 - T) * e / (1 - e)                                                    # ATT weights
    print("IPW (ATT)", round(Y[T == 1].mean() - (w @ Y) / w.sum(), 2))           # 2.67
    print("AIPW", np.mean(m1 - m0 + T * (Y - m1) / e - (1 - T) * (Y - m0) / (1 - e)))  # 3.0
    
    # (b) the simulated job-training study (earnings in 1000 $)
    def simulate(n=2000, seed=0):
        rng = np.random.default_rng(seed)
        age, educ = rng.uniform(18, 55, n), rng.integers(8, 17, n).astype(float)
        unemp = (rng.random(n) < 0.3).astype(float)
        re75 = np.where(unemp == 1, 0.0, rng.gamma(2.0, 4.0, n))          # earnings in 1975
        logit = -0.8 - 0.12 * (re75 - 8) + unemp - 0.03 * (age - 35) - 0.15 * (educ - 12)
        T = (rng.random(n) < 1 / (1 + np.exp(-logit))).astype(int)
        tau = 1.0 + 1.5 * unemp                                            # true effects
        Y0 = (3 + 0.8 * re75 + 0.4 * (educ - 12) + 0.1 * (age - 35)
              - 0.004 * (age - 35) ** 2 + rng.normal(0, 3, n))
        return np.column_stack([age, educ, re75, unemp]), T, Y0 + tau * T, tau
    
    X, T, Y, tau = simulate()
    Z = (X - X.mean(0)) / X.std(0)
    e = LogisticRegression(C=1e6).fit(Z, T).predict_proba(Z)[:, 1]
    m1 = LinearRegression().fit(X[T == 1], Y[T == 1]).predict(X)
    m0 = LinearRegression().fit(X[T == 0], Y[T == 0]).predict(X)
    nn = NearestNeighbors(n_neighbors=1).fit(Z[T == 0])
    match = Y[T == 0][nn.kneighbors(Z[T == 1])[1][:, 0]]
    w1, w0, wa = T / e, (1 - T) / (1 - e), (1 - T) * e / (1 - e)
    results = {
        "naive": Y[T == 1].mean() - Y[T == 0].mean(),
        "OLS coef": LinearRegression().fit(np.column_stack([T, X]), Y).coef_[0],
        "g-formula": np.mean(m1 - m0),
        "matching ATT": np.mean(Y[T == 1] - match),
        "IPW ATE": w1 @ Y / w1.sum() - w0 @ Y / w0.sum(),
        "IPW ATT": Y[T == 1].mean() - wa @ Y / wa.sum(),
        "AIPW ATE": np.mean(m1 - m0 + T * (Y - m1) / e - (1 - T) * (Y - m0) / (1 - e)),
    }
    print(f"truth: ATE {tau.mean():.2f}  ATT {tau[T == 1].mean():.2f}")
    for k, v in results.items():
        print(f"{k:13s} {v:6.2f}")
    # truth: ATE 1.45  ATT 1.76
    # naive          -3.12
    # OLS coef        1.32
    # g-formula       1.30
    # matching ATT    1.62
    # IPW ATE         0.99
    # IPW ATT         1.72
    # AIPW ATE        1.28
    

    LogisticRegression(C=1e6) turns off the default L2 penalty in practice: we want the propensity model itself, not a shrunken one. The notebook builds every estimator step by step, adds cross-fitting to AIPW and runs the 200-study experiment.

    6. Where it shows up #

    • Medicine and epidemiology. Observational drug-safety and effectiveness studies use propensity scores and IPW; target trial emulation (Hernán and Robins) designs the analysis as if it were a randomized trial and then adjusts with these tools. Marginal structural models extend IPW to treatments that change over time.
    • Tech products. Users opt in to features, subscriptions and notifications. When an A/B test is not possible, analysts estimate the effect with matching or AIPW on logged covariates, and report a sensitivity analysis.
    • Recommender systems and search. Users rate or click only what they were shown. Inverse propensity scoring (IPS) reweights the observed feedback by 1/P(shown)1/P(\text{shown}) to get unbiased estimates of ranking quality and to train debiased models (Schnabel et al. 2016; Joachims et al. 2017).
    • Off-policy evaluation. The value of a new policy from logs of an old policy is estimated with importance weights π(a∣x)/π0(a∣x)\pi(a \mid x)/\pi_0(a \mid x) and with doubly robust estimators (lesson 11; reinforcement learning 03).
    • Machine learning under covariate shift. Training points reweighted by ptest(x)/ptrain(x)p_{\text{test}}(x)/p_{\text{train}}(x), often estimated with a classifier that predicts "test or train": the same computation as a propensity score.
    • Survey statistics. The Horvitz–Thompson estimator was invented (1952) to weight survey respondents by the inverse of their probability of being sampled.
    • Science. Effects of policies, environmental exposures (air pollution and health) and land use are estimated from observational data with matching and weighting, together with sensitivity analysis.

    7. Common mistakes #

    • Adjusting for post-treatment variables. Covariates must be measured before the treatment. Adjusting for a mediator or a collider (lesson 04) creates bias, and no estimator can repair it. Check: draw the graph; for every covariate, ask "could the treatment change it?".
    • Judging the propensity model by AUC or accuracy. The target is balance, not prediction. A very high AUC signals poor overlap. Check: SMDs after weighting, propensity histograms.
    • Putting every predictor of TT into the propensity model. Instruments (causes of TT only) add variance and amplify any remaining bias. Include confounders and causes of YY.
    • Ignoring extreme weights. One unit with weight 500 can decide the estimate. Check: largest weight, ESS, a plot of the weights; try Hájek, trimming or overlap weights, and say which estimand you now estimate.
    • Mixing up the estimands. Matching treated units gives the ATT; IPW with 1/e1/e gives the ATE; a caliper or trimming gives the effect in a subpopulation. Report the target with the number.
    • Reading the OLS coefficient as the ATE. With heterogeneous effects, the coefficient of TT is a variance-weighted average of the effects, not the ATE. Use the g-formula with separate models for each arm.
    • "Balanced, so causal." Balance on measured XX says nothing about unmeasured confounders. Check: a sensitivity analysis (robustness value, E-value).
    • "Doubly robust means twice as safe." It means one of two models must be right. With both wrong, AIPW can be worse than either method alone.
    • Plain bootstrap for nearest-neighbor matching. It is not valid for matching with a fixed number of matches (Abadie and Imbens 2008). Use the analytic variance or a weighting estimator with the bootstrap.

    8. Check yourself #

    1. In a cell of 20 people, 5 are treated (e^=0.25\hat e = 0.25). Give the IPW weights for the ATE and the size of each weighted group.
      AnswerTreated: 1/0.25=41/0.25 = 4; controls: 1/0.75=4/31/0.75 = 4/3. Weighted treated: 5×4=205 \times 4 = 20; weighted controls: 15×4/3=2015 \times 4/3 = 20. Each group stands for all 20 people of the cell.
    2. Compute the effective sample size of the weights (2,2,2,2)(2, 2, 2, 2) and of (1,1,1,1,6)(1, 1, 1, 1, 6).
      Answer(8)2/16=4(8)^2/16 = 4: equal weights keep the full size. (10)2/(4+36)=100/40=2.5(10)^2/(4 + 36) = 100/40 = 2.5: one large weight makes five units worth only 2.5.
    3. Why does trimming units with e^∉[0.1,0.9]\hat e \notin [0.1, 0.9] change what you estimate? Give an example where it matters.
      AnswerThe estimate now averages the effect over the units that remain, not over the whole population. If the effect differs with XX and the trimmed units have different effects (in the figure of section 3.6, the units with large ∣x∣|x| have the largest effects), the trimmed target is different from the ATE (there, below 1).
    4. Write the AIPW estimator and show in one line why it is unbiased when μ^t=μt\hat\mu_t = \mu_t (and the weights are anything bounded).
      Answerτ^=1n∑i[μ^1−μ^0+Ti(Yi−μ^1)/e^i−(1−Ti)(Yi−μ^0)/(1−e^i)]\hat\tau = \frac1n\sum_i[\hat\mu_1 - \hat\mu_0 + T_i(Y_i - \hat\mu_1)/\hat e_i - (1 - T_i)(Y_i - \hat\mu_0)/(1 - \hat e_i)]. With μ^1=μ1\hat\mu_1 = \mu_1: E[T(Y−μ1(X))/e^(X)∣X]=e(X)(μ1(X)−μ1(X))/e^(X)=0\mathbb{E}[T(Y - \mu_1(X))/\hat e(X) \mid X] = e(X)(\mu_1(X) - \mu_1(X))/\hat e(X) = 0, so the correction terms have mean 0 and the estimator reduces to the g-formula.
    5. Compute the E-value for an observed risk ratio of 3, and for a protective risk ratio of 0.5.
      Answer3+3⋅2=3+2.45=5.453 + \sqrt{3 \cdot 2} = 3 + 2.45 = 5.45. For 0.5 use 1/0.5=21/0.5 = 2: 2+2=3.412 + \sqrt 2 = 3.41.
    6. A regression gives τ^=1.32\hat\tau = 1.32 with standard error 0.1540.154 and df=1994\mathrm{df} = 1994. Compute the robustness value.
      Answerf=1.32/(0.1541994)=1.32/6.88=0.192f = 1.32/(0.154\sqrt{1994}) = 1.32/6.88 = 0.192, so f2=0.0368f^2 = 0.0368. RV=12(0.03682+4⋅0.0368−0.0368)=12(0.386−0.037)=0.174\mathrm{RV} = \frac12(\sqrt{0.0368^2 + 4 \cdot 0.0368} - 0.0368) = \frac12(0.386 - 0.037) = 0.174. A confounder that explains 17.4% of the residual variance of both TT and YY would bring the estimate to 0.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. State conditional exchangeability in symbols and in words.

    2. What is positivity (overlap), and how much of it does the ATT need?

    3. Write the g-formula (standardization) for the ATE.

    4. What does the balancing theorem of the propensity score say?

    5. Write the Horvitz–Thompson IPW estimator of the ATE.

    6. Which weights make the control group look like the treated group (ATT)?

    7. Compute the effective sample size of the weights (1,1,1,1,6)(1, 1, 1, 1, 6).

    8. Define the standardized mean difference and the usual balance rule.

    9. What does "doubly robust" mean for AIPW?

    10. Compute the E-value for an observed risk ratio of 2.

    Open the review →

    9. Interview angle #

    • "How would you estimate the effect of a feature that users opted into?" — Draw the graph: what drives opting in and the outcome (activity before the launch, tenure, platform)? Use only pre-treatment covariates. Fit a propensity model, check overlap and balance, estimate with AIPW (or IPW and matching as checks), report a confidence interval and a sensitivity analysis. Say that the result depends on "no unmeasured confounding" and suggest a holdout or an encouragement experiment if possible.
    • "What is a propensity score and how do you check it?" — P(T=1∣X)P(T = 1 \mid X). It balances XX (Rosenbaum and Rubin). Check it by balance (SMDs after weighting below 0.1), overlap (histograms, largest weight, ESS) and calibration, not by AUC.
    • "What does doubly robust mean?" — An estimator that combines an outcome model and a propensity model and is consistent if either one is right. AIPW: regression estimate plus inverse-weighted residuals. Its bias is a product of the two errors, which is why it works well with ML models and cross-fitting (double ML).
    • "Matching or weighting?" — Matching is transparent and targets the ATT; it struggles with many covariates and its standard errors need care. Weighting targets the ATE or the ATT and uses all units, but is sensitive to extreme weights. AIPW is usually the best default.
    • "Your IPW estimate jumps when you remove one user. Why?" — That user has an extreme weight (propensity near 0 or 1): poor overlap. Look at the ESS, use Hájek or overlap weights, or trim and report the new estimand.

    10. Practice #

    The notebook for this lesson has five exercises, each with a check cell and a folded solution. Every exercise uses a simulation with a known true effect:

    1. standardize(df): the g-formula with one linear model per arm; compare it with the naive difference and the OLS coefficient.
    2. nn_match_att(df, caliper): nearest-neighbor matching on standardized covariates with NearestNeighbors; a balance table of SMDs before and after.
    3. ipw(df, e_hat, kind): the Horvitz–Thompson, Hájek and ATT versions with a LogisticRegression propensity model; weighted SMDs and the effective sample size.
    4. aipw(df) with 2-fold cross-fitting; the 2×22 \times 2 experiment with right and wrong models.
    5. Overlap: increase the confounding, compare the spread of IPW and AIPW, and see how trimming changes the estimand.

    11. Watch and read #

    The propensity score, its balancing property and the IPW estimator, with the derivation from the adjustment formula.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    A short overview of AIPW and matching, and a preview of double ML for lesson 08.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Matching on the propensity score step by step, with the balance check.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    How strong an unobserved confounder must be to change a conclusion, in a linear model.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The idea of matching in three minutes: compare each treated unit with a similar untreated unit.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play