Math for Causal Inference

Day 50. Structural Causal Models

A structural causal model writes each variable as a function of its direct causes and an exogenous disturbance. It generates the DAG, the joint distribution and, unlike a regression, answers questions about interventions.

Video coming soon
Learning outcomes
  • ●Define a structural causal model and draw the DAG it induces, including bidirected edges for dependent disturbances.
  • ●Compute means, variances and covariances implied by a linear SCM, using Σ = (I − B)⁻¹ Ω (I − B)⁻ᵀ.
  • ●Distinguish structural coefficients from regression coefficients and compute omitted-variable bias.
  • ●Explain observational equivalence, where different causal models produce the same data.
2-HOUR SESSION PLAN
Theory 25′Warm-up (1–5) 20′Proofs (6–10) 35′Applied (11–15) 25′Python & Lab 15′
Colab notebook (.ipynb) Jump to the simulator

Theory

Definition

A structural causal model (SCM) M=(U,V,F,P(U))\mathcal M = (\mathbf U, \mathbf V, \mathbf F, P(\mathbf U)) has:

  • exogenous variables U\mathbf U, determined outside the model, with distribution P(U)P(\mathbf U);
  • endogenous variables V=(V1,…,Vp)\mathbf V = (V_1, \dots, V_p);
  • one structural equation per endogenous variable,
Vi:=fi(pa⁡(Vi),Ui).V_i := f_i\big(\operatorname{pa}(V_i), U_i\big).

The symbol :=:= is an assignment: ViV_i is produced by its causes. Unlike an algebraic equation, it cannot be rearranged to "solve for" a cause.

The induced graph

Draw W→ViW \to V_i for each W∈pa⁡(Vi)W \in \operatorname{pa}(V_i). If the UiU_i are mutually independent the model is Markovian, the graph is a DAG, and the distribution of V\mathbf V factorises over it (Day 47). If some Ui,UjU_i, U_j are dependent (an omitted common cause), draw a bidirected edge Vi↔VjV_i \leftrightarrow V_j: the model is semi-Markovian. A bidirected edge is shorthand for Vi←U→VjV_i \leftarrow U \to V_j with UU unobserved.

Linear SCMs

Stack the equations: V=BV+ε\mathbf V = \mathbf B\mathbf V + \boldsymbol\varepsilon, where BijB_{ij} is the coefficient of VjV_j in the equation for ViV_i and Var⁡(ε)=Ω\operatorname{Var}(\boldsymbol\varepsilon) = \boldsymbol\Omega (diagonal if Markovian). Solving,

V=(I−B)−1ε,Σ=Var⁡(V)=(I−B)−1Ω(I−B)−⊤.\mathbf V = (\mathbf I - \mathbf B)^{-1}\boldsymbol\varepsilon, \qquad \boldsymbol\Sigma = \operatorname{Var}(\mathbf V) = (\mathbf I - \mathbf B)^{-1}\boldsymbol\Omega(\mathbf I - \mathbf B)^{-\top}.

Because the graph is acyclic, B\mathbf B is nilpotent and (I−B)−1=I+B+B2+…(\mathbf I - \mathbf B)^{-1} = \mathbf I + \mathbf B + \mathbf B^2 + \dots: entry (i,j)(i, j) is the total effect of VjV_j on ViV_i, the sum over directed paths of the products of their coefficients.

Structural versus regression coefficients

In Y:=βX+γA+UYY := \beta X + \gamma A + U_Y, β\beta is causal: change XX by one unit, holding AA and UYU_Y fixed, and YY moves by β\beta. The regression slope of YY on XX alone is

Cov⁡(X,Y)Var⁡(X)=β+γ Cov⁡(X,A)Var⁡(X),\frac{\operatorname{Cov}(X, Y)}{\operatorname{Var}(X)} = \beta + \gamma\,\frac{\operatorname{Cov}(X, A)}{\operatorname{Var}(X)},

which equals β\beta only if the omitted cause AA is uncorrelated with XX. The SCM tells you which regression (if any) recovers β\beta.

Observational equivalence

Different SCMs can generate the same distribution. With Gaussian variables, X→YX \to Y and Y→XY \to X fit any correlation equally well. Data alone cannot decide causal direction there; assumptions (time order, experiments, non-Gaussianity, Day 98) must.

What an SCM adds

An SCM supports three kinds of questions (Pearl's ladder, Day 59): association (from P(V)P(\mathbf V)), intervention (replace an equation, Day 51) and counterfactuals (keep each unit's UU, Day 59).

Part 1 · Warm-up

Exercise 1 · From equations to graph

Draw the graph for A:=UAA := U_A, S:=fS(A,US)S := f_S(A, U_S), O:=fO(S,UO)O := f_O(S, U_O), W:=fW(A,S,O,UW)W := f_W(A, S, O, U_W), where USU_S and UWU_W are correlated and the others independent.

Show solution

Step 1. Directed edges from the arguments: A→SA \to S, S→OS \to O, A→WA \to W, S→WS \to W, O→WO \to W.

Step 2. Correlated disturbances US,UWU_S, U_W: bidirected edge S↔WS \leftrightarrow W.

Answer: a semi-Markovian graph; the bidirected edge says an unobserved factor (say, motivation) affects both schooling and wages.

Exercise 2 · Mean and variance

X:=UXX := U_X with UX∼N(2,1)U_X \sim N(2, 1) and Y:=3+0.5X+UYY := 3 + 0.5X + U_Y with UY∼N(0,0.75)U_Y \sim N(0, 0.75) independent. Find E[Y]E[Y], Var⁡(Y)\operatorname{Var}(Y) and corr⁡(X,Y)\operatorname{corr}(X, Y).

Show solution

Step 1. E[Y]=3+0.5(2)=4E[Y] = 3 + 0.5(2) = 4.

Step 2. Var⁡(Y)=0.52(1)+0.75=1\operatorname{Var}(Y) = 0.5^2(1) + 0.75 = 1.

Step 3. Cov⁡(X,Y)=0.5Var⁡(X)=0.5\operatorname{Cov}(X, Y) = 0.5\operatorname{Var}(X) = 0.5, so corr⁡=0.5/1×1=0.5\operatorname{corr} = 0.5/\sqrt{1 \times 1} = 0.5.

Exercise 3 · Total effect by paths

In a linear SCM, X→2M→3YX \xrightarrow{2} M \xrightarrow{3} Y and X→−1YX \xrightarrow{-1} Y. Find the total effect of XX on YY.

Show solution

Step 1. Directed paths: X→M→YX \to M \to Y with product 2×3=62 \times 3 = 6; X→YX \to Y with −1-1.

Step 2. Sum: 6−1=56 - 1 = 5.

Answer: 5.

Exercise 4 · The covariance matrix

For X:=εXX := \varepsilon_X, Y:=2X+εYY := 2X + \varepsilon_Y with Var⁡(εX)=1\operatorname{Var}(\varepsilon_X) = 1 and Var⁡(εY)=3\operatorname{Var}(\varepsilon_Y) = 3, compute Σ\boldsymbol\Sigma using (I−B)−1(\mathbf I - \mathbf B)^{-1}.

Show solution

Step 1. With order (X,Y)(X, Y): B=(0020)\mathbf B = \begin{pmatrix} 0 & 0 \\ 2 & 0 \end{pmatrix}, so (I−B)−1=I+B=(1021)(\mathbf I - \mathbf B)^{-1} = \mathbf I + \mathbf B = \begin{pmatrix} 1 & 0 \\ 2 & 1 \end{pmatrix}.

Step 2. Ω=diag⁡(1,3)\boldsymbol\Omega = \operatorname{diag}(1, 3).

Step 3.

Σ=(1021)(1003)(1201)=(1227).\boldsymbol\Sigma = \begin{pmatrix} 1 & 0 \\ 2 & 1 \end{pmatrix}\begin{pmatrix} 1 & 0 \\ 0 & 3 \end{pmatrix}\begin{pmatrix} 1 & 2 \\ 0 & 1 \end{pmatrix} = \begin{pmatrix} 1 & 2 \\ 2 & 7 \end{pmatrix}.

Answer: Var⁡(X)=1\operatorname{Var}(X) = 1, Cov⁡(X,Y)=2\operatorname{Cov}(X, Y) = 2, Var⁡(Y)=4+3=7\operatorname{Var}(Y) = 4 + 3 = 7.

Exercise 5 · Assignment, not equation

From Y:=2X+UYY := 2X + U_Y, a student writes X=(Y−UY)/2X = (Y - U_Y)/2 and concludes that raising YY raises XX. What is wrong?

Show solution

Step 1. The structural equation describes how YY is produced; XX has its own equation, X:=fX(pa⁡(X),UX)X := f_X(\operatorname{pa}(X), U_X), which does not involve YY.

Step 2. Intervening on YY replaces YY's equation and leaves XX's untouched (Day 51).

Answer: algebraic rearrangement is valid for the observed values but not for causal claims; XX does not respond to changes in YY.

Part 2 · Proofs

Exercise 6 · Markovian SCMs factorise

Prove that if the UiU_i are independent and the graph is acyclic, then P(v)=∏iP(vi∣pa⁡(vi))P(\mathbf v) = \prod_i P(v_i \mid \operatorname{pa}(v_i)).

Show solution

Step 1. Order the variables topologically. By recursive substitution, each predecessor VjV_j (j<ij < i) is a function of U1,…,Ui−1U_1, \dots, U_{i-1} only.

Step 2. UiU_i is independent of (U1,…,Ui−1)(U_1, \dots, U_{i-1}), hence of the predecessors (V1,…,Vi−1)(V_1, \dots, V_{i-1}).

Step 3. So given the predecessors, Vi=fi(pa⁡(Vi),Ui)V_i = f_i(\operatorname{pa}(V_i), U_i) has a distribution that depends only on pa⁡(Vi)\operatorname{pa}(V_i): P(vi∣v1,…,vi−1)=P(vi∣pa⁡(vi))P(v_i \mid v_1, \dots, v_{i-1}) = P(v_i \mid \operatorname{pa}(v_i)).

Step 4. Substitute into the chain rule. ■\blacksquare

Exercise 7 · Total effects from (I − B)⁻¹

Prove that for an acyclic linear SCM, (I−B)−1=∑k=0p−1Bk(\mathbf I - \mathbf B)^{-1} = \sum_{k=0}^{p-1}\mathbf B^k and that entry (i,j)(i, j) for i≠ji \ne j is the sum over directed paths from VjV_j to ViV_i of the products of coefficients.

Show solution

Step 1. B\mathbf B is nilpotent (Bp=0\mathbf B^p = 0, Day 46), so (I−B)∑k=0p−1Bk=I−Bp=I(\mathbf I - \mathbf B)\sum_{k=0}^{p-1}\mathbf B^k = \mathbf I - \mathbf B^p = \mathbf I.

Step 2. (Bk)ij=∑Bim1Bm1m2⋯Bmk−1j(\mathbf B^k)_{ij} = \sum B_{i m_1}B_{m_1 m_2}\cdots B_{m_{k-1} j} over intermediate nodes: each non-zero term is a directed path Vj→Vmk−1→⋯→ViV_j \to V_{m_{k-1}} \to \dots \to V_i of length kk, weighted by its coefficients.

Step 3. Summing over kk adds all directed paths. ■\blacksquare

Exercise 8 · Omitted-variable bias

Let Y:=βX+γA+UYY := \beta X + \gamma A + U_Y with UYU_Y independent of (X,A)(X, A). Prove Cov⁡(X,Y)/Var⁡(X)=β+γCov⁡(X,A)/Var⁡(X)\operatorname{Cov}(X, Y)/\operatorname{Var}(X) = \beta + \gamma\operatorname{Cov}(X, A)/\operatorname{Var}(X).

Show solution

Step 1. Cov⁡(X,Y)=βVar⁡(X)+γCov⁡(X,A)+Cov⁡(X,UY)\operatorname{Cov}(X, Y) = \beta\operatorname{Var}(X) + \gamma\operatorname{Cov}(X, A) + \operatorname{Cov}(X, U_Y).

Step 2. The last term is 0 by independence.

Step 3. Divide by Var⁡(X)\operatorname{Var}(X). ■\blacksquare

Exercise 9 · Reversing a Gaussian arrow

Let X∼N(0,1)X \sim N(0, 1) and Y:=bX+UYY := bX + U_Y, UY∼N(0,1−b2)U_Y \sim N(0, 1 - b^2), ∣b∣<1|b| < 1. Construct an SCM with Y→XY \to X that generates the same joint distribution.

Show solution

Step 1. The original model gives Var⁡(Y)=b2+(1−b2)=1\operatorname{Var}(Y) = b^2 + (1 - b^2) = 1 and Cov⁡(X,Y)=b\operatorname{Cov}(X, Y) = b.

Step 2. Try Y:=UY′∼N(0,1)Y := U'_Y \sim N(0, 1) and X:=bY+UX′X := bY + U'_X with UX′∼N(0,1−b2)U'_X \sim N(0, 1 - b^2) independent.

Step 3. Then Var⁡(X)=b2+1−b2=1\operatorname{Var}(X) = b^2 + 1 - b^2 = 1 and Cov⁡(X,Y)=b\operatorname{Cov}(X, Y) = b.

Step 4. Both are bivariate normal with mean 0 and the same covariance matrix, so the distributions coincide. ■\blacksquare

Exercise 10 · When regression is structural

In a Markovian linear SCM, prove that regressing ViV_i on all its parents recovers the structural coefficients.

Show solution

Step 1. Vi=∑j∈pa⁡(i)BijVj+εiV_i = \sum_{j \in \operatorname{pa}(i)} B_{ij}V_j + \varepsilon_i.

Step 2. Each parent is a function of the disturbances of its own ancestors, and ViV_i is not among them (acyclicity). With independent disturbances, εi\varepsilon_i is independent of all parents.

Step 3. So E[εi∣pa⁡(Vi)]=0E[\varepsilon_i \mid \operatorname{pa}(V_i)] = 0: the OLS moment condition holds at the true coefficients, and the population regression coefficients equal BijB_{ij}. ■\blacksquare

Part 3 · Applied

Exercise 11 · Returns to schooling with ability

An SCM for log wages: ability A∼N(0,1)A \sim N(0, 1); years of schooling S:=12+2A+USS := 12 + 2A + U_S with Var⁡(US)=4\operatorname{Var}(U_S) = 4; log⁡W:=1.5+0.08S+0.10A+UW\log W := 1.5 + 0.08S + 0.10A + U_W, all disturbances independent. What does a regression of log⁡W\log W on SS alone estimate? What about on SS and AA?

Show solution

Step 1. Var⁡(S)=22(1)+4=8\operatorname{Var}(S) = 2^2(1) + 4 = 8 and Cov⁡(S,A)=2\operatorname{Cov}(S, A) = 2.

Step 2. By Exercise 8, the short-regression slope is 0.08+0.10×2/8=0.08+0.025=0.1050.08 + 0.10 \times 2/8 = 0.08 + 0.025 = 0.105.

Step 3. With AA included, the regression is on all parents of log⁡W\log W, so it recovers 0.080.08 (Exercise 10).

Answer: 10.5% per year without ability, 8% with it. The 2.5-point gap is ability bias; in practice AA is unobserved, which motivates instruments (Phase 5).

Exercise 12 · A binary vaccine model

UI,UV,UEU_I, U_V, U_E are independent uniform on (0,1)(0, 1). Exposure I:=1[UI<0.1]I := \mathbf 1[U_I < 0.1], vaccination V:=1[UV<0.6]V := \mathbf 1[U_V < 0.6], protection E:=1[UE<0.9]E := \mathbf 1[U_E < 0.9] (the vaccine works for 90%), disease D:=I (1−VE)D := I\,(1 - VE). Compute P(D=1)P(D = 1), P(D=1∣V=1)P(D = 1 \mid V = 1) and P(D=1∣V=0)P(D = 1 \mid V = 0).

Show solution

Step 1. D=1D = 1 requires exposure and no protection: P(D=1)=P(I=1)(1−P(V=1)P(E=1))=0.1(1−0.6×0.9)=0.046P(D = 1) = P(I = 1)\big(1 - P(V = 1)P(E = 1)\big) = 0.1(1 - 0.6 \times 0.9) = 0.046.

Step 2. Given V=1V = 1: P(D=1∣V=1)=0.1×(1−0.9)=0.01P(D = 1 \mid V = 1) = 0.1 \times (1 - 0.9) = 0.01.

Step 3. Given V=0V = 0: P(D=1∣V=0)=0.1P(D = 1 \mid V = 0) = 0.1.

Answer: 4.6%, 1% and 10%. Because VV is independent of UIU_I and UEU_E here, the observed risk ratio 0.1 equals the causal one.

Exercise 13 · Monetary policy multipliers

A linear macro SCM: interest rate RR affects investment (R→−2IR \xrightarrow{-2} I) and consumption (R→−0.5CR \xrightarrow{-0.5} C); investment raises consumption (I→0.3CI \xrightarrow{0.3} C, via income); output Y:=I+C+GY := I + C + G. Compute the total effect of RR on YY by paths and by (I−B)−1(\mathbf I - \mathbf B)^{-1}.

Show solution

Step 1. Directed paths R→YR \to Y: R→I→YR \to I \to Y: −2×1=−2-2 \times 1 = -2; R→C→YR \to C \to Y: −0.5×1=−0.5-0.5 \times 1 = -0.5; R→I→C→YR \to I \to C \to Y: −2×0.3×1=−0.6-2 \times 0.3 \times 1 = -0.6.

Step 2. Total: −2−0.5−0.6=−3.1-2 - 0.5 - 0.6 = -3.1.

Step 3. With order (R,I,C,Y)(R, I, C, Y), the matrix computation (code below) gives the entry [(I−B)−1]Y,R=−3.1[(\mathbf I - \mathbf B)^{-1}]_{Y, R} = -3.1.

Answer: a one-point rise in the policy rate lowers output by 3.1 units; the regression of YY on RR alone recovers this only if RR is set independently of the disturbances.

Exercise 14 · Exercise and fitness

A health survey finds corr⁡(exercise hours,fitness score)=0.6\operatorname{corr}(\text{exercise hours}, \text{fitness score}) = 0.6, both standardised and normal. Write two SCMs, one with exercise causing fitness and one with fitness causing exercise, that both fit the data exactly. What evidence could separate them?

Show solution

Step 1. Model 1: X:=UX∼N(0,1)X := U_X \sim N(0, 1), Y:=0.6X+UYY := 0.6X + U_Y with Var⁡(UY)=1−0.36=0.64\operatorname{Var}(U_Y) = 1 - 0.36 = 0.64.

Step 2. Model 2: Y:=UY′∼N(0,1)Y := U'_Y \sim N(0, 1), X:=0.6Y+UX′X := 0.6Y + U'_X with Var⁡(UX′)=0.64\operatorname{Var}(U'_X) = 0.64.

Step 3. By Exercise 9 both give the same bivariate normal distribution.

Answer: only extra information can separate them: an experiment (randomise an exercise programme), time order in panel data (exercise this month, fitness next month), or non-Gaussian features (Day 98).

Exercise 15 · Making a bidirected edge explicit

A health economist models hospital quality QQ and patient survival YY with Q→YQ \to Y, and notes that wealthier areas have both better hospitals and healthier patients, but area wealth is not measured. Write a semi-Markovian SCM and show what the regression of YY on QQ estimates in the linear case Q:=aH+UQQ := aH + U_Q, Y:=βQ+cH+UYY := \beta Q + cH + U_Y, with unobserved wealth H∼N(0,1)H \sim N(0, 1).

Show solution

Step 1. Graph: Q→YQ \to Y and Q↔YQ \leftrightarrow Y (shorthand for Q←H→YQ \leftarrow H \to Y with HH unobserved).

Step 2. Var⁡(Q)=a2+Var⁡(UQ)\operatorname{Var}(Q) = a^2 + \operatorname{Var}(U_Q) and Cov⁡(Q,H)=a\operatorname{Cov}(Q, H) = a.

Step 3. By Exercise 8 the slope is β+c a/(a2+Var⁡(UQ))\beta + c\,a/(a^2 + \operatorname{Var}(U_Q)).

Answer: biased upward when wealth raises both quality and survival (a,c>0a, c > 0). Days 52–56 ask when such bias can be removed with the variables you do observe.

Verify in Python

import numpy as np

def implied_cov(B, Omega):
    """Covariance of V = B V + eps for an acyclic linear SCM."""
    T = np.linalg.inv(np.eye(len(B)) - B)
    return T @ Omega @ T.T, T

# Exercise 4
S, _ = implied_cov(np.array([[0, 0], [2, 0.]]), np.diag([1, 3.]))
print("Sigma:\n", S)

# Exercise 11: ability bias (order A, S, logW)
B = np.zeros((3, 3)); B[1, 0] = 2; B[2, 1] = .08; B[2, 0] = .10
S, _ = implied_cov(B, np.diag([1, 4, .25]))
print("short slope:", round(S[1, 2] / S[1, 1], 4))
coef = np.linalg.solve(S[:2, :2], S[:2, 2])
print("long regression (A, S):", coef.round(4))

# Exercise 13: total effects, order R, I, C, Y
B = np.zeros((4, 4)); B[1, 0] = -2; B[2, 0] = -.5; B[2, 1] = .3; B[3, 1] = 1; B[3, 2] = 1
_, T = implied_cov(B, np.eye(4))
print("total effect R -> Y:", T[3, 0].round(3))

# Exercise 12: binary vaccine model by simulation
rng = np.random.default_rng(50); n = 2_000_000
I = rng.random(n) < .1; V = rng.random(n) < .6; E = rng.random(n) < .9
D = I & ~(V & E)
print(f"P(D) {D.mean():.4f}  P(D|V=1) {D[V].mean():.4f}  P(D|V=0) {D[~V].mean():.4f}")

# Exercise 14: two directions, one distribution
X = rng.normal(size=n); Y = .6 * X + np.sqrt(.64) * rng.normal(size=n)
Y2 = rng.normal(size=n); X2 = .6 * Y2 + np.sqrt(.64) * rng.normal(size=n)
print("cov X->Y model:", np.cov(X, Y).round(3).tolist(), " cov Y->X model:", np.cov(X2, Y2).round(3).tolist())

Key takeaways

  • An SCM assigns each variable a mechanism Vi:=fi(pa⁡(Vi),Ui)V_i := f_i(\operatorname{pa}(V_i), U_i); independent disturbances give a DAG, dependent ones bidirected edges.
  • In linear SCMs, (I−B)−1(\mathbf I - \mathbf B)^{-1} collects total effects and Σ\boldsymbol\Sigma follows from it; regression recovers a structural coefficient only when the regressors block every non-causal path.
  • Data can be silent about direction: different SCMs can be observationally equivalent.

Simulation Lab: A Structural Model of Wages

Open full screen →

Structural equations for ability, schooling and wages: the short regression slope versus the structural return.

2357.51012.51517.520years of schooling Slog wage
AbilitySchoolingLog wage
structural β
0.080
short regression
0.105
β + c·a/Var(S)
ability bias
0.025
Var(S) = 8.00
regression on schooling onlystructural effect βhigh abilitylow ability

Structural equations: Ability A ~ N(0, 1); Schooling S := 12 + a·A + U_S; log wage := 1.5 + β·S + c·A + U_W. The regression of log wages on schooling alone (orange) has slope β + c·a / Var(S); the structural effect is β (green). Colour shows ability.

Day 49Day 51