Interactive figures
Every figure in the track. Each one is a small experiment: drag, slide, and watch the numbers. The link under each figure takes you to the lesson that explains it.
Lesson 1 · Correlation vs causation
Switch between the five sources and press New sample a few times. All five scatter plots look alike: the correlation is about (about for selection). The small graph shows how the data were made. Arrows: aqua = causal path, magenta = a non-causal path that creates the association, violet node = common cause, yellow filled node = the variable we select on. For chance, the first sample is the strongest of 20 unrelated pairs; a new sample of the same pair loses the correlation.
Move the three sliders. The magenta line is the slope of the pooled regression of on ; the aqua dashed line has the true causal slope . Points are violet, darker for larger . Press Hold Z fixed: the yellow lines are the fitted lines at (regression of on and ), and only points in thin slices of stay bright. Set ("no causal effect"): the pooled slope stays positive. Set : the pooled slope equals .
Move the sliders to change the share of large stones among the patients of A (blue) and B (orange). Each line joins a treatment's small-stone rate (left end) and its large-stone rate (right end). The big dot is the pooled rate: it slides along the line as the case mix changes. The aqua rings are the standardized rates: both treatments evaluated on the same stone mix. Find the share for A at which the pooled ranking flips.
Click a rung to see its question, its notation, an example from machine learning, what it needs beyond data, and the lessons of this track that teach it. Supervised learning lives on rung 1. Most of this track (lessons 02–08, 10, 11) is about rung 2; lesson 09 climbs to rung 3.
Lesson 2 · Potential outcomes and experiments
Switch between "what nature knows" and "what we see". In the second view the potential outcome that did not happen is a grey "?". Change who takes tutoring, or click a cell to move one student. Blue rows are treated, orange rows are controls. The bars show the naive difference split into the effect on the treated (ATT) and the selection bias; the dashed aqua line is the true ATE. Notice: when the weakest choose, the naive difference is although every effect is positive.
Press "Randomize once" a few times, then "Randomize 1000 times" and "All 70 assignments". Each experiment gives tutoring to 4 of the 8 students by lottery. The blue histogram collects the estimates; the aqua line is the true ATE, 6.25. Notice that the mean of the histogram is on the aqua line, but single estimates spread with an SD of about 11. Switch to the Fisher view: one experiment, the sharp null, and the exact p-value (observed statistic in magenta).
Switch between the three designs and press "Assign again"; then press "Run 500 experiments". The top panel shows the age of the treated (above the axis) and the controls (below); dashed lines mark the group means. Age raises the outcome. In the bottom panel each row collects 500 estimates; the aqua line is the true effect, 5. Self-selection (magenta) is biased by more than 10 points. Complete randomization is centered on 5 with an SD of about 2.5. Blocking by age is also centered on 5, with an SD of about 1.
Lesson 3 · Causal graphs and d-separation
Switch between chain, fork and collider, then press "Condition on B". The scatter shows against for 300 units from the model in the panel. When you condition, only the units in a narrow slice of stay bright (yellow), with their own fitted line. In the chain and the fork the slice is a round cloud (the association disappears). In the collider the full cloud is round but the slice slopes down. The panel shows the sample correlation next to the exact value.
Move the share selected from 100% down to 5%. Each dot is a person with two independent traits. The yellow dots are selected because the sum of the traits is in the top share; the dashed magenta line is the selection threshold. The correlation in the whole sample stays near 0, but inside the selection it becomes more and more negative: about when half are selected and about for the top 10%. The exact value comes from the truncated normal distribution.
Pick two nodes with "From" and "To", then click nodes to put them into the conditioning set (yellow). The panel lists every path between the two nodes and says why each one is open or blocked. Open non-causal paths are thick magenta, open directed paths are thick aqua; dashed violet nodes are unobserved. Try Sprinkler and Rain with , then add Wet. Use the other graphs, or build your own with "add node" and "add edge".
Move the sliders, or press "Random CPTs". The joint table below the graph is recomputed from the factorization. The checks on the right test five conditional independences. The three that the graph implies stay at gap 0.000 for every choice of numbers. The other two are usually dependent. Press "Make P(sprinkler) the same in both seasons": now Sprinkler and Rain are independent without conditioning, but only because of these special numbers.
Press "Cancel the paths", then change or . The scatter shows against with the fitted line (ink) and the total effect (dashed aqua). When the line is flat: the data look as if had no effect on . Given , the partial correlation is still , so the dependence comes back. Faithfulness fails only on this thin set of weights.
Lesson 4 · The do-operator and adjustment
Switch between "seeing" and "doing", and move the slider "Severity → Drug" (the strength of that arrow). The magenta bars are what we see, ; the aqua bars are the truth under intervention, . In the doing view the arrow into the drug is cut and the share of severe patients stays at 0.5. With strength 0.6 the drug looks slightly harmful when we only see (), although it raises recovery by . With strength 0 the two views agree.
Click nodes to build the adjustment set (yellow). The panel lists the backdoor paths from the treatment to and says whether the set satisfies the backdoor criterion. Open backdoor paths are thick magenta, causal paths aqua. In the butterfly graph, try (it opens ), then . In "mediator", see why must stay out.
Tick variables to add them to the regression of on . The readout gives the coefficient of with its standard error, its value with infinite data, the truth (1) and the naive estimate. Press "Run 200 samples" to see the spread of the estimate for the current set. Compare , and (same answer, different spread), then add , or . Hidden variables are dashed violet.
Move the sliders, then press "Add the arrow U → Tar". The data are a sample of 20,000 people with smoking, tar and cancer; the genotype is never in the data. The table computes the frontdoor formula step by step from the sample. Compare the estimate (ink) with the truth from the hidden model and with the naive difference. With the default numbers the truth is and the naive difference . With the arrow U → Tar, condition 2 fails and the formula is biased even with infinite data.
Optional. Press "Next step" to go through the derivation, then add the arrow U → M and go through it again. For each step the figure draws the modified graph that the rule needs (removed edges faded, with ✕), the conditioning set (yellow) and the result of the d-separation test. Open paths that make a test fail are thick magenta. With U → M, steps 2, 3 and 7 fail, so the rules cannot derive the formula.
Lesson 5 · Matching and propensity scores
Switch between the weights. "raw" shows the data: treated units sit at large , where is high anyway, so the naive difference is too large. "IPW (ATE)" gives each unit the weight or ; the dot area shows the weight. Notice the large control dots at large : 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 drops to about 0. "weights for ATT" makes the controls look like the treated group; "IPW, trimmed" drops units with outside . The aqua curves are the true and , 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.
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 values: a treated unit may take a control far away along a dashed line of equal . 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 for covariate matching, of for propensity matching.)
Increase the confounding strength and watch the histograms of : 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 : 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.
Make one model wrong at a time. "wrong" models use instead of , so they miss the confounding through . 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.
Drag the black point to choose the strength of a hypothetical confounder ; 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 , standard error ). 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.
Lesson 6 · Instrumental variables
Move the sliders and watch three lines. Dots are units: blue for , orange for . The magenta OLS line is tilted by the hidden confounder (dashed violet node). The dark IV line goes through the two big dots, the group means; its slope is the Wald estimate. The dashed aqua line has the true slope . Set confounding to 0: OLS becomes right. Choose weak instrument: the big dots almost touch and the IV line jumps with each new sample. Choose exclusion broken: the IV line is wrong by , and nothing in the picture warns you.
Change the shares and switch the types on and off. Each circle is a person; filled means treated. Aqua compliers follow the coin, blue always-takers are always filled, orange never-takers are never filled, and magenta defiers do the opposite. Set the types to hidden to see what the data shows. With no defiers the Wald ratio equals the compliers' effect, whatever the always-takers' effect is. Add 10% defiers and give them a different effect: the ratio leaves the LATE.
Choose a strength and press Run 500 samples. Each run simulates 500 data sets of 200 units with a true effect of 1 (aqua line) and strong confounding. The magenta histogram is OLS: precise and wrong (dashed line: its population value). The dark histogram is IV. With it is centered on the truth. Lower the strength: the IV histogram widens, its center moves towards OLS, and the share of 95% intervals that contain the truth drops (about 70% at ).
Lesson 7 · RDD, DiD and synthetic control
Move the bandwidth and switch the fit. Dots are units: blue treated (), orange control. The dashed aqua curves are the true regression functions; the thin dotted ones are the potential outcomes we never see on each side. The yellow window holds the units the local linear fit uses. Make large with curvature on: the lines miss the curve and the jump is biased. Make small: the jump gets noisy (press New sample). Try global degree 5 and press New sample a few times: the ends of the curves swing. Switch to fuzzy: the share treated jumps by only 0.5, and the effect is the ratio of the two jumps.
Bend the trends and switch the view. Blue: treated group, orange: control group, policy from period 5 (shaded). The dashed dark line is the DiD counterfactual: the control line moved to the treated group's level before the policy. The dashed aqua line is the true of the treated group, which only a simulation can show. With trend violation 0 they agree. Set the violation to 0.2 from the start, then open event study: the coefficients before the policy slope away from 0, a warning you can see. Now choose only after the policy: the pre-period looks perfect, but the estimate is still biased.
Raise the growth of the effect and shrink the never-treated group. Each line is a group; a line is orange while its group is untreated and blue once it is treated. The grid below shows the weight TWFE gives to each treated group-period; magenta cells have negative weights. With growth 0, TWFE (magenta readout) equals the true average (aqua). With growth 2 and a small never-treated group, TWFE falls far below the truth and can turn negative, while the group-time average stays exact.
Press Fit to the pre-period, then open placebo test. The blue line is the treated unit; the dark line is the synthetic control; the dashed aqua line is the treated unit's true . Donors with weight are yellow (thicker = more weight). With equal weights the synthetic line misses the pre-period, and the post-period gap is not the effect. After Fit it tracks the treated unit before period 20, and the gap after it is close to the true effect. In the placebo view, the treated unit's gap stands out among the donors' gaps.
Lesson 8 · Causal ML
Start with the T-learner at 10% treated. Treated and control points come from the same wiggly baseline; the true effect is smooth. The fitted models are drawn in the group colors, and the black curve is the estimate . Notice the false wiggles: the treated model is too smooth to follow the baseline. Switch to X: the wiggles disappear, because the X-learner fits a smooth model to imputed effects. Now pick S and raise the effect size to 3: the estimate is pulled toward 0. Pick DR at 10% treated, then at 50%: the DR-learner is noisy where the propensity is near 0 and good with balanced groups. The readout compares the ATE from with the true ATE and the naive difference in means, which is confounded here because treatment is more likely for large .
Step through the four panels. In panel 0 the naive slope of on is about 1.3, far from the true (dashed). Panels 1 and 2 fit and on (black curve). In panel 3, the slope of the residuals with a linear fit is about 1.1: it equals the coefficient of in to all digits (FWL), but it is still biased, because the confounding is curved. Switch to flexible: the residuals lose the curved confounding too, and the slope is close to 0.5.
Two views of why DML works. 200 simulations: each run draws a data set from a partially linear model with and computes three estimates, with -nearest-neighbor regression as the ML model. At the outcome model nearly memorises each point: the grey histogram (DML without cross-fitting) shrinks toward 0, but cross-fitting (black) stays centered. Move the slider to or : the outcome model is now too smooth, and the plug-in estimate moves away from 0.5, while DML stays close. The readout also shows how often the 95% CI covers . Errors multiply: exact formulas for a model where both nuisance models are off by ; the plug-in bias grows like , the DML bias like . Simulated in your browser with the model described in the notes of section 3.3.
Compare adaptive and honest trees. The left square shows the true effect in four regions; the right square shows the tree's leaves, shaded by the estimated effect. Magenta outlines mark leaves whose 95% CI misses the true average effect of the leaf. Press Run 100 trees at depth 4 in each mode: the adaptive tree's intervals cover the truth only about 75–80% of the time, the honest tree's about 95%. Then compare the MSE at depth 2 and at depth 6: honesty costs accuracy for shallow trees (half the data per task), and it is about equal or slightly better for deep trees.
Choose a budget and a cost. A simulated shop ran a randomized coupon test on 20,000 customers. The oracle sorts by the true effects; the black uplift model is a noisy version of them; the response model sorts by the probability to buy with a coupon. Notice that the response model's curve first goes down: the likely buyers buy anyway, and the coupon slightly lowers the purchases of some of them. Move the budget slider and read the extra purchases. Raise the cost per coupon: the best budget moves left, to the point where the next customer's effect is smaller than the cost. Switch to the weak model to see a flatter curve.
Lesson 9 · Counterfactuals and mediation
Press "Next step" three times. The yellow nodes are observed or inferred, hidden noises are dashed violet, and the variable we set is blue. In step 1 the wide prior of (grey) becomes a single value: . In step 3 the counterfactual is a single value, , while the interventional distribution (grey) is wide and centered at 0. Now choose "two noises": the effect of also varies between units, so one equation cannot fix two unknowns. The counterfactual becomes a narrow distribution, still much narrower than the interventional one. Set : the counterfactual is exactly the observed (consistency).
Move the last slider. The grid shows 100 units by type: caused (aqua), always (dark), prevented (violet) and never (light). The two bars are what a randomized trial measures; they do not change when you move the slider, but the share of "caused" among the exposed who had the outcome does. The dot is PN for this model, the yellow interval is everything the data allow. Try "no average effect": with , PN can be anything from 0 to 1.
Choose "no interaction" first. The bars show NDE, NIE and TE: truth (aqua), the estimate of the mediation formula (dark) and the product of coefficients (magenta) from 500 simulated units with a randomized . Without an interaction all three agree: NIE , NDE . Choose "interaction": the effect of depends on , so NIE and the product rule is wrong (magenta readout). The controlled direct effects CDE(0) and CDE(2) now differ too. Choose "hidden confounder": a hidden (dashed violet) affects and . The total effect is still right (T is randomized), but both splits are biased.
Drag the applicant, then change . The model approves when (grey region). The explanation (magenta arrow) is the nearest approved point, which changes only income . In the feature SCM income causes savings with strength , so acting on income also moves savings along the aqua dashed direction; the dashed magenta arrow shows where a person who follows the explanation really ends. With the explanation overshoots: the recourse (dark arrow) reaches the boundary with a smaller change (1.64 instead of 2.30 for the default applicant). Choose "income lowers savings": following the explanation leaves the applicant rejected.
Lesson 10 · Causal discovery
Pick a graph or click the edge slots to build your own DAG on 3 or 4 nodes. The second panel is the CPDAG of its class; below are all DAGs of the class (your DAG has a colored frame). Edges that belong to a v-structure are yellow in your DAG. Notice that the chain, the reversed chain and the fork form one class of 3, while the collider is alone. Ignore "Intervene on" for now; section 3.6 uses it.
Press Step to run PC one decision at a time. The current step is yellow: the removed edge (dashed) with the nodes of its separating set filled, or the edges being oriented. Start with the oracle tests (exact d-separation in the true graph), then switch to data tests and change and . In data mode, decisions that differ from the truth are magenta. "Show the true graph" reveals the DAG that made the data, in aqua. Notice that even with perfect tests the edges at stay undirected.
Switch the noise between uniform, Laplace and Gaussian, and draw new samples. Left: the data. Middle: the residual of the causal fit against , in aqua. Right: the residual of the anti-causal fit against , magenta when a test finds it dependent. With uniform noise the right panel is a diamond: the spread of the residual shrinks at the ends. HSIC (a kernel test of independence) gives a small p-value only in the anti-causal direction. With Gaussian noise both panels look like round clouds: the direction cannot be found this way.
Draw new random graphs, change the weight range, then switch the data to "standardized". The bars show the exact variance of each variable in the causal order (log scale); nodes without parents are aqua. Varsortability is the share of cause → effect pairs in which the cause has the smaller variance; it turns magenta when it is above 0.75. Notice that it is high for every weight range, because every non-root variable has its own unit noise plus the noise of its causes. After standardizing it is 0.5: the variance no longer tells the order.
Choose the node to intervene on (blue). The chain has a class of 4 DAGs. An experiment on orients and , and then rule R1 orients : the class has one member. An experiment on leaves open (2 DAGs). Try the diamond: an experiment on orients nothing new, because its edges are already in the v-structure.
Lesson 11 · Causality in ML practice
Start with "link flips". Points are colored by label (blue , orange ). The magenta boundary belongs to logistic regression on both features, the aqua dashed boundary to the model with the core feature only. In training the magenta model reaches about 0.94; on test data where the link flips it falls below 0.5, worse than a coin. The core-only model stays near 0.84. Now choose "strong shortcut" (no shift): the magenta model is accurate on average, but its worst group (birds on the "wrong" background) is near 0.4. Choose "no shift" with : the weight of drops to about 0.
Move the shift slider. The top chart shows (blue) and (orange), dashed before and solid after the shift. The bottom chart shows . With "X → Y" and "distribution of the cause" (covariate shift), the posterior curve does not move (aqua), and the old threshold stays the best. Switch to "Y → X": now the shift changes (label shift), the posterior moves (magenta), and the best threshold moves away from 0. The table says which factors are fixed and which change. Choose "mechanism of the effect": in both graphs the conditional you wanted to learn changes.
Read the three panels. In each panel, a regression of on one candidate set is fitted separately in three environments; the lines join its coefficients (solid: , dashed: ). Here is the cause of and is a child of whose mechanism changes. Only has the same coefficient everywhere (aqua: accepted by the test, ); the sets with are rejected. has the smallest training error (about 0.48 vs 0.97) but a much larger error in a new environment (about 2.9 vs 1.0). Move the slider to 0.1: with weak differences the test cannot reject much, and ICP returns the empty set: no conclusion, but no wrong one.
Press "Run 200 logs", then move the first slider. Each histogram shows one estimator over 200 simulated logs; the aqua line is the true value . The logging policy prefers an old favourite action with probability ; the target policy picks other actions. The direct method uses a reward model that ignores the context: its spread is small, but it is centered near 0.45, far from the truth. IPS, SNIPS and DR are centered on the truth. Move to 0.95: the largest weight grows to 40, the effective sample size of a log of 500 falls to about 13, and the standard deviation of IPS is about 0.2. SNIPS and DR are less noisy.