Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Lab 3 · Seeing versus doing: causal inference by simulation

Level: Levels 2–4 · Prerequisites: L2-07 (read a causal graph), L2-08 (observe or intervene), L4-01 (structural causal models), L4-03 (confounders, mediators, colliders), L4-04 (back-door adjustment), L4-05 (front-door identification)

What you’ll learn:

  • How an intervention do(X=x)do(X=x) differs from filtering records where X=xX=x, inside a structural causal model.

  • How big confounding bias is. When the confounder is measured, back-door adjustment (standardization) and inverse probability weighting remove it.

  • How the front-door formula recovers an effect through a mediator, even when the confounder is hidden.

  • Why conditioning on a common effect (a collider) creates a correlation that is not causal.

Open in Colab

1 · Predict → Run → Explain: the engine’s model

qcai.science.causal encodes the binary structural causal model Z→X→Y←ZZ\to X\to Y\leftarrow Z:

Z∼Bernoulli(0.5),P(X=1∣Z)={0.8Z=10.2Z=0,P(Y=1∣X,Z)=0.1+0.2X+0.5Z.Z\sim\text{Bernoulli}(0.5),\quad P(X=1\mid Z)=\begin{cases}0.8 & Z=1\\0.2 & Z=0\end{cases},\quad P(Y=1\mid X,Z)=0.1+0.2X+0.5Z .

Predict. The treatment XX adds 0.2 to the chance of YY. Will the observed difference P(Y=1∣X=1)−P(Y=1∣X=0)P(Y=1\mid X=1)-P(Y=1\mid X=0) also be 0.2?

P(Y=1 | X=1) = 0.700    P(Y=1 | do(X=1)) = 0.550
P(Y=1 | X=0) = 0.200    P(Y=1 | do(X=0)) = 0.350
observed contrast = 0.500,  causal effect (ATE) = 0.200,  bias = 0.300
Engine and bias-formula checks passed.

Explain. Filtering on X=1X=1 selects mostly people with Z=1Z=1, and ZZ raises YY by itself. So the observed contrast 0.5 mixes the treatment effect (0.2) with a confounding bias (0.3). The intervention do(X=x)do(X=x) replaces the mechanism that assigns XX and leaves ZZ’s distribution unchanged. Then P(Y=1∣do(X=1))−P(Y=1∣do(X=0))P(Y=1\mid do(X=1))-P(Y=1\mid do(X=0)) equals the effect 0.2 Pearl, 2009.

The check cell confirms a general identity: bias == (effect of ZZ on YY) ×\times (how much more common ZZ is among the treated). When ZZ does not influence who is treated (low = high), the bias is zero.

Move the slider to change how strongly ZZ affects YY. The left panel compares seeing (filtering) with doing (intervening).

Loading...

2 · Three graphs to keep in mind

These are the three causal graphs used in this lab. Use the buttons to switch between them. Dashed grey nodes are hidden (not measured).

Loading...
{'backdoor_ok': True, 'backdoor_empty': False, 'fd_xm': True, 'fd_my': True, 'collider_marginal': True, 'collider_given_C': False}

A publication-style version of the same three graphs:

<Figure size 1365x416 with 3 Axes>

3 · Predict → Run → Explain: back-door adjustment on 20,000 records

We now draw 20,000 records from the engine’s model and forget that we know the truth.

Predict. Which of these will land near the true effect 0.2: the naive difference, the stratified (standardized) estimate, or the inverse-probability-weighted (IPW) estimate?

naive            +0.4978
standardization  +0.1857
ipw              +0.1857
do_simulated     +0.2011
truth: ATE = 0.200, population observed contrast = 0.500
Back-door checks passed.

Explain. The naive difference reproduces the biased population contrast.

Standardization compares treated and untreated within each level of ZZ. It then averages with the population weights P(z)P(z). This is the back-door adjustment formula. It is valid because ZZ blocks the only back-door path X←Z→YX\leftarrow Z\to Y Pearl, 2009.

IPW reweights each record by 1/P(X=x∣Z)1/P(X=x\mid Z). This builds a pseudo-population in which ZZ no longer predicts XX Hernan & Robins, 2020. Here ZZ is binary and the propensities are estimated separately in each stratum. In that case the two estimators give the same number, as the check cell confirms. Both need positivity: every stratum of ZZ must contain treated and untreated records.

4 · Front-door: a hidden confounder and a mediator

Now the confounder UU is hidden. Treatment works only through a measured mediator MM:

U∼Bern(0.5),P(X=1∣U)=0.2+0.6U,P(M=1∣X)=0.1+0.8X,P(Y=1∣M,U)=0.1+0.5M+0.3U.U\sim\text{Bern}(0.5),\quad P(X{=}1\mid U)=0.2+0.6U,\quad P(M{=}1\mid X)=0.1+0.8X,\quad P(Y{=}1\mid M,U)=0.1+0.5M+0.3U .

The true effect is 0.5×0.8=0.40.5\times0.8=0.4. Because UU is unmeasured, no back-door adjustment is possible. The front-door criterion still applies, for three reasons. MM intercepts every directed path from XX to YY. There is no unblocked back-door path from XX to MM. And XX blocks every back-door path from MM to YY Pearl, 1995.

Predict. Will “adjust for MM” (stratify on the mediator) recover 0.4?

true effect 0.4000 | front-door formula (population) 0.4000 | naive 0.5800 | adjust-for-M 0.1800
Front-door identification checks passed.
naive          +0.5894
adjust_for_M   +0.1783
frontdoor      +0.4110
Front-door estimation checks passed.

Explain. Stratifying on MM blocks the very path the effect travels along. It also leaves the hidden-confounder bias in place. It lands near 0.18.

The front-door formula instead estimates two pieces it can identify, then chains them Pearl, 1995. The first is the effect of XX on MM (no back door). The second is the effect of MM on YY (back door blocked by XX). The population calculation shows that the formula equals the true effect exactly. The simulation shows that the sample estimate comes close.

The forest plot sums up every estimator in this lab with 95 % bootstrap percentile intervals (200 resamples). A 95 % interval is expected to miss the truth in about one sample in twenty. So read the printed coverage line instead of assuming every interval covers. The point is the contrast. The valid estimators sit near the truth. The biased ones miss by many times their interval width. Here standardization and IPW are the same number (one estimate, not two). Its interval just misses 0.2. This is an instance of the one-in-twenty miss, not a bias.

naive (A)              +0.498  95% CI [+0.487, +0.511]
standardization (A)    +0.186  95% CI [+0.173, +0.200]
IPW (A)                +0.186  95% CI [+0.173, +0.200]
naive (B)              +0.589  95% CI [+0.578, +0.601]
adjust for M (B)       +0.178  95% CI [+0.159, +0.200]
front-door (B)         +0.411  95% CI [+0.392, +0.427]
bootstrap standard errors: {'naive (A)': 0.0063, 'standardization (A)': 0.0075, 'IPW (A)': 0.0075, 'naive (B)': 0.0061, 'adjust for M (B)': 0.0112, 'front-door (B)': 0.009}
interval covers the true effect: {'naive (A)': False, 'standardization (A)': False, 'IPW (A)': False, 'naive (B)': False, 'adjust for M (B)': False, 'front-door (B)': True}
<Figure size 1040x468 with 1 Axes>

5 · Predict → Run → Explain: collider bias

Two traits XX and YY are generated independently. A record is kept only if a combination of them is high, C=1[X+Y+0.5 ε>t]C=\mathbb 1[X+Y+0.5\,\varepsilon>t]. Think of admission based on two scores.

Predict. Among the kept records, will XX and YY still look unrelated?

correlation in all 20,000 records: -0.001
keep if score > -1.5: kept 0.84 of records, correlation among kept -0.195
keep if score > -1.0: kept 0.75 of records, correlation among kept -0.263
keep if score > -0.5: kept 0.63 of records, correlation among kept -0.328
keep if score > +0.0: kept 0.50 of records, correlation among kept -0.393
keep if score > +0.5: kept 0.37 of records, correlation among kept -0.449
keep if score > +1.0: kept 0.26 of records, correlation among kept -0.517
keep if score > +1.5: kept 0.16 of records, correlation among kept -0.575
keep if score > +2.0: kept 0.09 of records, correlation among kept -0.615
Collider checks passed.
Loading...

Explain. In the kept group, a record with a low XX must have had a high YY to pass. So the two become negatively correlated, even though neither causes the other. Conditioning on a common effect opens the path X→C←YX\to C\leftarrow Y. This is one form of selection bias Hernan & Robins, 2020. Adjusting for a variable is therefore not always safe. Adjusting for a confounder removes bias. Adjusting for a collider creates it.

Going deeper

Intervention in an SCM

For the engine’s model, the truncated factorization gives P(Y=1∣do(X=x))=∑zP(z) P(Y=1∣x,z)=0.1+0.2x+0.5 P(Z=1)P(Y=1\mid do(X=x))=\sum_z P(z)\,P(Y=1\mid x,z)=0.1+0.2x+0.5\,P(Z=1) Pearl, 2009.

Back-door adjustment

Suppose ZZ blocks every back-door path from XX to YY and contains no descendant of XX. Then

P(y∣do(x))=∑zP(y∣x,z) P(z).P(y\mid do(x))=\sum_z P(y\mid x,z)\,P(z).

IPW

With propensity e(z)=P(X=1∣Z=z)∈(0,1)e(z)=P(X=1\mid Z=z)\in(0,1),

E[Y1]−E[Y0]=E ⁣[XYe(Z)]−E ⁣[(1−X)Y1−e(Z)],\mathbb E[Y^{1}]-\mathbb E[Y^{0}]=\mathbb E\!\left[\frac{XY}{e(Z)}\right]-\mathbb E\!\left[\frac{(1-X)Y}{1-e(Z)}\right],

which equals standardization when both are computed nonparametrically Hernan & Robins, 2020.

Front-door adjustment

Suppose MM satisfies the front-door criterion relative to (X,Y)(X,Y) and P(x,m)>0P(x,m)>0. Then

P(y∣do(x))=∑mP(m∣x)∑x′P(y∣m,x′) P(x′)P(y\mid do(x))=\sum_m P(m\mid x)\sum_{x'}P(y\mid m,x')\,P(x')

This is Pearl’s front-door adjustment Pearl, 1995.

Confounding bias in the engine’s model

  P(Y=1∣X=1)−P(Y=1∣X=0)=effect+confound⋅[P(Z=1∣X=1)−P(Z=1∣X=0)]\;P(Y{=}1\mid X{=}1)-P(Y{=}1\mid X{=}0)=\text{effect}+\text{confound}\cdot\big[P(Z{=}1\mid X{=}1)-P(Z{=}1\mid X{=}0)\big]. This is checked numerically above for several parameter sets.

Exercises

Solution

The observed contrast equals the effect, 0.2, and the bias is 0. Without a Z→YZ\to Y arrow there is no open back-door path.

Solution

It is 0 again. The Z→XZ\to X arrow is removed, so ZZ is equally common among treated and untreated. This is why randomized experiments do not need back-door adjustment.

Solution

No. The true effect becomes 0.1+0.4×0.8=0.420.1+0.4\times0.8=0.42. The population front-door formula gives a different number (computed in the check cell). The reason is that MM no longer intercepts every directed path from XX to YY.

Check yourself

direct-arrow model: true effect 0.4200, front-door formula 0.3200
All checks passed.
References
  1. Pearl, J. (2009). Causal inference in statistics: An overview. Statistics Surveys, 3(none), 96–146. 10.1214/09-ss057
  2. Hernan, M., & Robins, J. (2020). Causal Inference: What If. https://miguelhernan.org/whatifbook
  3. Pearl, J. (1995). Causal diagrams for empirical research. https://ftp.cs.ucla.edu/pub/stat_ser/R218-B.pdf