ML Systems Lab Open interactive version →
Foundational 29 min read causal inferencepotential outcomesATERubin

Potential Outcomes Framework

Rubin causal model, ATE/ATT, fundamental problem of causal inference

User 47 got the discount email and spent $100 over the next month. Would they have spent that anyway, without it? You'd need a second version of User 47 who never got the email — and it doesn't exist; you only watch what actually happened. Same gap, reversed, for User 12: no email, spent $70. You'd need the version of them who did get it, and you don't have that version either. Whichever branch of the world happened for a person is the only branch you ever see.

That missing branch has a name — the counterfactual, the outcome a unit would have had under the treatment it didn't receive. And the fact that it's missing for every unit, always, is the fundamental problem of causal inference: you observe exactly one of two potential outcomes per unit, never both.

Pause here: if the other branch never exists for anyone, how could any experiment ever produce a causal number at all? Hold that question — it resolves once you stop trying to estimate any one person's effect.

Rubin's potential outcomes framework gives this gap symbols: Y_i(1) is unit i's outcome if treated, Y_i(0) if untreated. For User 47, Y_47(1) = $100 is the branch actually watched — whatever assigned the treatment (here, a random draw into the campaign) decided which branch got realized; Y_47(0) is the missing counterfactual. For User 12 it's reversed: Y_12(0) = $70 is observed, Y_12(1) is missing. The individual treatment effect, ITE_i = Y_i(1) − Y_i(0), needs both numbers for one person — exactly what the fundamental problem rules out. No dataset, however large, ever gives you one person's ITE.

So estimate the average instead: the Average Treatment Effect, ATE = E[Y_i(1) − Y_i(0)]. Here's why that rescues you. Suppose — a God's-eye view no real dataset gives you, for one paragraph only — you could see both branches for four users: User 47, $100 treated / $80 untreated, effect $20. User 12, $90 / $70, effect $20. User 8, $60 / $50, effect $10. User 90, $40 / $30, effect $10. True ATE = (20+20+10+10)/4 = $15 — computable only because you were God for a paragraph.

In the real campaign only one column per user survives. Say the actual draw put User 47 and User 8 in treatment, User 12 and User 90 in control. All you can compute is the observed difference in means: mean($100, $60) − mean($70, $30) = $80 − $50 = $30 — double the true $15. Randomization didn't fail; one draw carries sampling noise like any estimator does. The guarantee is about averaging this estimator over every possible draw: with 4 users split 2-and-2 there are C(4,2) = 6 possible draws, and the same difference-in-means computed under each gives $55, $30, $10, $20, $0, and −$25 — averaging to 90/6 = $15, exactly the true ATE. One draw is noisy; the estimator is unbiased across draws. That's the entire justification for flipping the coin: not that one experiment nails the number, but that the design makes the noise average out to zero around the truth.

That guarantee needs three assumptions, each of which can break in this campaign. SUTVA (Stable Unit Treatment Value Assumption): treating User 47 doesn't change User 12's outcome. Break it — say User 47 forwards the discount code to User 12 — and User 12's "untreated" $70 is no longer the baseline, it's contaminated by spillover. Consistency: the outcome observed for a treated unit really is Y_i(1) as defined — a different subject line is a different treatment, not noise around one. Positivity (overlap): every user has some chance of landing in either arm — if users who spent nothing last month are never in the campaign at all, any number reported for them is pure extrapolation, not estimation. A fourth assumption sits underneath those three, under a different name: ignorability (also called unconfoundedness, or no unmeasured confounders) — treatment assignment has to be independent of the potential outcomes, at least once you condition on what you've measured. The random draw into the campaign satisfies it by construction, the same way it satisfies positivity; outside a randomized design it means no factor you failed to measure is quietly driving both who got treated and what they would have earned either way. Like the other three, it is a claim about how the world generated the data, not something the same data can certify — testing it would need both Y_i(1) and Y_i(0) for one unit, exactly what the fundamental problem rules out. The best you can do is balance checks, placebo tests, and sensitivity analysis on how strong a hidden confounder would have to be to overturn the result.

Estimand choice is a decision made before the method, not after. ATE averages across all users. ATT — the effect on the treated — averages only over users who actually got the email. CATE is the effect for a slice sharing feature X = x. These are different numbers with different policy implications: using ATT — the effect among users who happened to get the campaign — to justify emailing the entire user base is an estimand error, since the users already reached may respond nothing like the users who never got the chance.

None of this means causal inference is impossible without perfect data. It means every causal number carries assumptions the same data can't verify — SUTVA, consistency, and positivity are claims about how the world generated the data, not properties a p-value certifies. Argue them from domain knowledge, design them away through randomization, or bound them with sensitivity analysis — never assume they hold just because the difference in means came out significant.

Key points

Takeaway

Causal inference is a missing data problem: for every unit you observe one potential outcome and must assume something about the other — and those assumptions are unverifiable from the same data you used to estimate the effect.

Recap

Check your understanding

Q1. Observed data shows users who saw an ad (T=1) had 20% higher conversion than users who did not (T=0). Can you conclude the ad caused 20% lift? What would you need to make a causal claim?

Q2. A clinical trial shows ATE = +5 points on health scale. A policymaker wants to mandate the drug for everyone. Is ATE the right estimand? What if trial enrolled only volunteers?

Q3. You run an A/B test for a new social sharing feature. Control group engagement unexpectedly increased. Select the two statements that correctly explain what is happening and how to fix it.

Q4. Why can the ignorability assumption never be tested from data? What is the best you can do to support it?

Try it interactively

ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.

Open ML Systems Lab →