Causal Inference

Last updated: August 2026

Disclaimer: These are my personal notes compiled for my own reference and learning. They may contain errors, incomplete information, or personal interpretations. While I strive for accuracy, these notes are not peer-reviewed and should not be considered authoritative sources. Please consult official textbooks, research papers, or other reliable sources for academic or professional purposes.

1. Potential outcomes and the fundamental problem

Definition (Potential outcomes)

For unit $i$ and binary treatment $D_i\in\{0,1\}$, $Y_i(1)$ and $Y_i(0)$ are the outcomes that would occur under treatment and control respectively. The individual treatment effect is $Y_i(1)-Y_i(0)$; the observed outcome is $Y_i = D_iY_i(1)+(1-D_i)Y_i(0)$.

The Average Treatment Effect is $\mathrm{ATE}=E[Y_i(1)-Y_i(0)]$; the Average Treatment Effect on the Treated is $\mathrm{ATT}=E[Y_i(1)-Y_i(0)\mid D_i=1]$ — a different quantity in general, since the treated population need not resemble the population at large.

The fundamental problem of causal inference

For any unit $i$, only one of $Y_i(1),Y_i(0)$ is ever observed — whichever $D_i$ selects. The individual treatment effect is not a quantity any amount of data on unit $i$ alone can recover; every method in this note instead identifies some population-level average by substituting a comparison group for unit $i$'s unobserved counterfactual.

This framing matters because it makes precise what regression coefficients estimate under what conditions — and, by the same token, precisely why the regression methods note's OLS machinery does not automatically answer a causal question just because it is applied to observational data.

2. Identification assumptions, and why each is needed

3. What a naive comparison actually estimates

Proposition (Decomposition of the naive difference in means)

$$E[Y_i\mid D_i=1] - E[Y_i\mid D_i=0] = \underbrace{E[Y_i(1)-Y_i(0)\mid D_i=1]}_{\mathrm{ATT}} + \underbrace{E[Y_i(0)\mid D_i=1] - E[Y_i(0)\mid D_i=0]}_{\text{selection bias}}.$$

Proof. $E[Y_i\mid D_i=1]=E[Y_i(1)\mid D_i=1]$ and $E[Y_i\mid D_i=0]=E[Y_i(0)\mid D_i=0]$ directly from $Y_i=D_iY_i(1)+(1-D_i)Y_i(0)$. Add and subtract $E[Y_i(0)\mid D_i=1]$: $$E[Y_i(1)\mid D_i=1] - E[Y_i(0)\mid D_i=0] = \big(E[Y_i(1)\mid D_i=1]-E[Y_i(0)\mid D_i=1]\big) + \big(E[Y_i(0)\mid D_i=1]-E[Y_i(0)\mid D_i=0]\big).$$ The first bracket is $\mathrm{ATT}$ by definition; the second is the selection bias term.

The selection bias term compares what the treated group's outcome would have been without treatment to the control group's actual outcome — a difference that has nothing to do with the treatment effect and vanishes only under ignorability, since $(Y_i(0))\perp D_i \Rightarrow E[Y_i(0)\mid D_i=1]=E[Y_i(0)\mid D_i=0]$. This decomposition is the formal version of "correlation is not causation": the naive comparison always estimates $\mathrm{ATT}+\text{selection bias}$, and every identification strategy in this note is a different way of arguing the selection bias term is zero (or of estimating it separately, as in DiD, Section 7).

4. Randomized experiments

Proposition

If $D_i$ is assigned independently of $(Y_i(0),Y_i(1))$ (e.g. by a coin flip), then ignorability holds unconditionally, and $E[Y_i\mid D_i=1]-E[Y_i\mid D_i=0]$ is unbiased for the ATE.

This is immediate from Section 3: random assignment makes $D_i\perp(Y_i(0),Y_i(1))$ by construction (not by an assumption requiring justification from domain knowledge), so the selection bias term is exactly zero and $\mathrm{ATT}=\mathrm{ATE}$ (the treated group is, in expectation, a random sample of the whole population). This is precisely why randomized experiments are the benchmark the rest of this note's methods are built to approximate under weaker, observational conditions.

5. Instrumental variables and the Wald estimator

When treatment is not randomly assigned and no covariate set plausibly satisfies ignorability, an instrument $Z_i$ can substitute for randomization if it satisfies:

Derivation (Wald estimator)

Under a constant-effects linear model $Y_i=\alpha+\tau D_i+u_i$ with $\mathrm{Cov}(Z_i,u_i)=0$ (implied by independence and exclusion): $\mathrm{Cov}(Z_i,Y_i) = \tau\,\mathrm{Cov}(Z_i,D_i) + \mathrm{Cov}(Z_i,u_i) = \tau\,\mathrm{Cov}(Z_i,D_i)$, so

$$\tau_{\mathrm{IV}} = \frac{\mathrm{Cov}(Z_i,Y_i)}{\mathrm{Cov}(Z_i,D_i)},$$

well-defined precisely because relevance rules out division by zero.

Two-stage least squares generalizes this beyond a single binary instrument: regress $D$ on $Z$ (and covariates) to get fitted values $\hat D$, then regress $Y$ on $\hat D$. By the regression methods note's projection view of OLS (Section 2 there), $\hat D=P_{\mathrm{col}(Z)}D$ is exactly the part of $D$'s variation spanned by the instrument — 2SLS estimates the causal effect using only the treatment variation that the (assumed exogenous) instrument itself explains, discarding the rest as potentially confounded.

6. Regression discontinuity

When treatment is assigned by whether a running variable $X_i$ crosses a known cutoff $c$ (e.g. a test score threshold for a scholarship), units just above and just below $c$ are, absent any special reason for anything else to also change discontinuously at $c$, comparable — differing systematically only in treatment status.

Definition (Sharp RDD estimand)

$$\tau_{\mathrm{RDD}} = \lim_{x\to c^+} E[Y_i\mid X_i=x] \;-\; \lim_{x\to c^-} E[Y_i\mid X_i=x].$$

This is, precisely, a claim that $x\mapsto E[Y_i\mid X_i=x]$ has a jump discontinuity at $c$ in the sense of the continuity note (Section 4 there) — the one-sided limits both exist, and their difference (rather than their common value, which would signal no effect) is the causal estimate. In practice, each one-sided limit is estimated by local linear regression on data within a bandwidth $h$ of $c$, exactly the two separate fits shown in the figure below.

Scatter plot of an outcome variable against a running variable, with local linear regression fits on either side of a cutoff at zero, showing a vertical jump between the two fitted lines at the cutoff.
Figure — RDD is literally a one-sided-limit estimation problem. Simulated data with a true jump $\tau=2.0$ at the cutoff $X=0$. Local linear regressions fit separately on each side within a bandwidth $h=0.2$ (shaded) estimate the two one-sided limits; their difference, $\hat\tau_{\mathrm{RDD}}=1.89$, recovers the true jump closely. Points far from the cutoff (outside the shaded band) are shown for context but not used in the local estimates — a design choice, not an incidental one: local linear regression trades away the far-from-cutoff data specifically to avoid the discontinuity estimate being contaminated by curvature in $E[Y\mid X=x]$ unrelated to the treatment jump itself.

7. Difference-in-differences and parallel trends

With outcomes observed pre- and post-treatment for both a treated and an untreated group, DiD identifies a treatment effect under an assumption weaker than unconditional ignorability:

Parallel trends assumption

$$E[Y_i(0)_{\mathrm{post}} - Y_i(0)_{\mathrm{pre}} \mid D_i=1] = E[Y_i(0)_{\mathrm{post}} - Y_i(0)_{\mathrm{pre}} \mid D_i=0]$$

— absent treatment, the treated group's outcome would have trended the same as the control group's, even if their levels differ (unlike ignorability, this permits arbitrary time-invariant differences between groups).

Proposition

Under parallel trends, $\widehat{\mathrm{ATT}} = \big(\bar Y_{1,\mathrm{post}}-\bar Y_{1,\mathrm{pre}}\big) - \big(\bar Y_{0,\mathrm{post}}-\bar Y_{0,\mathrm{pre}}\big)$ is unbiased for the ATT in the post period.

Proof. $\bar Y_{1,\mathrm{post}}-\bar Y_{1,\mathrm{pre}} = E[Y_i(1)_{\mathrm{post}}-Y_i(0)_{\mathrm{pre}}\mid D_i=1]$ (the treated group's pre-period outcome is $Y_i(0)_{\mathrm{pre}}$, since treatment has not occurred yet). Add and subtract $E[Y_i(0)_{\mathrm{post}}\mid D_i=1]$: this equals $\mathrm{ATT} + E[Y_i(0)_{\mathrm{post}}-Y_i(0)_{\mathrm{pre}}\mid D_i=1]$. Subtracting the control group's observed change $\bar Y_{0,\mathrm{post}}-\bar Y_{0,\mathrm{pre}}=E[Y_i(0)_{\mathrm{post}}-Y_i(0)_{\mathrm{pre}}\mid D_i=0]$ and invoking parallel trends cancels the trend terms exactly, leaving $\mathrm{ATT}$.
Line plot showing pre and post period outcomes for a treated group and a control group, with a dashed counterfactual line showing what the treated group's post-period outcome would have been under parallel trends, and the gap between the actual and counterfactual outcome marked as the estimated ATT.
Figure — The parallel-trends counterfactual, made visible. The control group's change (blue, $2.0\to3.0$) defines the trend the treated group is assumed to have shared absent treatment; projecting that same trend from the treated group's pre-period level (dashed) gives the counterfactual $3.0\to4.0$. The gap between the treated group's actual post-period outcome and this counterfactual, $\widehat{\mathrm{ATT}}=5.5-4.0=1.5$, is exactly the proof's algebra made geometric — and exactly why parallel trends failing (the dashed line being the wrong slope) would bias this gap in either direction.

8. The propensity score theorem

Conditioning on a high-dimensional $X_i$ to satisfy ignorability runs into overlap problems quickly (Section 2) — few or no comparable units may share an identical $X_i$. The propensity score, $e(X_i)=P(D_i=1\mid X_i)$, gives a way to condition on a single scalar instead.

Theorem (Rosenbaum–Rubin, 1983)

If $(Y_i(0),Y_i(1))\perp D_i \mid X_i$, then $(Y_i(0),Y_i(1))\perp D_i \mid e(X_i)$.

Proof. It suffices to show $P(D_i=1\mid Y_i(0),Y_i(1),e(X_i)) = e(X_i)$. By the tower property, conditioning first on the finer information $(Y_i(0),Y_i(1),X_i)$ and then averaging over $X_i$ given $e(X_i)$: $$P(D_i=1\mid Y_i(0),Y_i(1),e(X_i)) = E\big[P(D_i=1\mid Y_i(0),Y_i(1),X_i) \,\big|\, Y_i(0),Y_i(1),e(X_i)\big].$$ By the hypothesis $(Y_i(0),Y_i(1))\perp D_i\mid X_i$, the inner probability equals $P(D_i=1\mid X_i)=e(X_i)$ — a function of $X_i$ that is already exactly determined by the conditioning variable $e(X_i)$ itself, so the outer expectation just returns $e(X_i)$ unchanged.

This is a genuine dimension-reduction result, not merely a convenient approximation: it says that matching or weighting on the scalar $e(X_i)$ alone recovers exactly the same identification as conditioning on the full covariate vector $X_i$, provided the (unverifiable in general, but sometimes very plausible) ignorability assumption holds for $X_i$ in the first place. In practice $e(X_i)$ is unknown and estimated (typically by logistic regression of $D$ on $X$), which introduces its own estimation-error considerations not covered by the theorem itself.

9. Computation

The figures above are generated by causal-inference/generate_figures.py. The snippet below runs the RDD and DiD estimators shown in the figures, and separately verifies the omitted-variable-bias mechanism behind Section 3's selection-bias term: a naive regression that omits a confounder $X$ affecting both treatment and outcome is biased by exactly $\gamma\cdot\delta$, where $\gamma$ is $X$'s effect on $Y$ and $\delta$ is the regression coefficient of $X$ on $D$.

import numpy as np

rng = np.random.default_rng(2)
n = 5000
X = rng.normal(0, 1, n)                     # confounder
D = 0.5 * X + rng.normal(0, 1, n)           # treatment depends on the confounder
tau_true, gamma = 2.0, 1.5                  # true effect, and X's effect on Y
Y = 1 + tau_true * D + gamma * X + rng.normal(0, 1, n)

naive = np.linalg.lstsq(np.column_stack([np.ones(n), D]), Y, rcond=None)[0]
full = np.linalg.lstsq(np.column_stack([np.ones(n), D, X]), Y, rcond=None)[0]
delta = np.linalg.lstsq(np.column_stack([np.ones(n), D]), X, rcond=None)[0][1]

print(f"naive tau_hat (omits X): {naive[1]:.4f}   (true tau = {tau_true})")
print(f"full  tau_hat (controls X): {full[1]:.4f}")
print(f"predicted bias = gamma*delta = {gamma*delta:.4f}   actual bias = {naive[1]-tau_true:.4f}")

Actual output:

naive tau_hat (omits X): 2.5876   (true tau = 2.0)
full  tau_hat (controls X): 1.9987
predicted bias = gamma*delta = 0.5826   actual bias = 0.5876

The predicted and actual bias agree closely: controlling for the confounder recovers the true effect almost exactly, while omitting it produces bias numerically consistent with Section 3's decomposition — the naive coefficient is genuinely $\mathrm{ATE}+\text{selection bias}$, not merely "less accurate."

10. Common pitfalls

Pitfall — Ignorability is not testable from data alone

Unlike overlap (checkable — do treated and untreated units coexist at every covariate value present in the data), ignorability is a claim about unobserved potential outcomes and can never be directly verified, only argued for on substantive grounds (or replaced by a research design — randomization, an instrument, a discontinuity — that does not require it to hold for arbitrary unobserved confounders).

Pitfall — A "significant" pre-trend test does not prove parallel trends

Similar pre-period trends across groups are consistent with, but do not prove, the assumption in Section 7 — parallel trends is a statement about the post-period counterfactual, which is by construction unobserved. Pre-trend similarity is suggestive evidence, not verification.

Pitfall — Weak instruments make the Wald estimator unreliable, not just imprecise

As $\mathrm{Cov}(Z_i,D_i)\to0$, Section 5's estimator's denominator approaches zero, and even small violations of the exclusion restriction get amplified without bound in the ratio — a "weak" instrument does not merely widen confidence intervals modestly, it can make the point estimate itself dominated by whatever small direct effect $Z$ has on $Y$, in violation of exclusion.

Pitfall — RDD requires no manipulation of the running variable at the cutoff

If units can influence which side of $c$ they land on (e.g. a student who knows the exact scholarship cutoff score retaking a test to just clear it), the comparability of units just above and below $c$ breaks — those just above are no longer a "similar but treated" version of those just below, but a selected group of manipulators. Checked in practice via a density test for a discontinuity in the running variable itself at $c$.

11. Connections

12. References