Contents/ Part XXIV · Advanced & Applied Topics/ Chapter 143

Causal Inference

Prediction asks what usually happens next. Causal inference asks a harder question: what happens if we intervene? Raising a price, sending a coupon, launching a program, each is an action whose effect you cannot read off a correlation. This chapter is the toolkit for estimating what an action actually causes, even when you were never able to run a clean experiment.

⏱️ ~25 min read
🐍 Notebook included
📊 Chapter 143

Back in the correlation chapter the warning was blunt: correlation is not causation. This chapter is the constructive sequel. When you want to know whether a treatment causes an outcome, and a randomized experiment is off the table, causal inference gives you a disciplined way to get an answer, and, just as important, to know when you cannot. The whole field turns on one uncomfortable fact: you only ever see what did happen, never the counterfactual of what would have happened otherwise.

The causal effect of a treatment on a unit is the difference between its outcome with the treatment and its outcome without it, the two potential outcomes Y(1) and Y(0). A confounder is a variable that influences both who gets treated and the outcome, creating a correlation that is not a causal effect.
The fundamental problem of causal inference

For any one customer you can enroll them in the program or not, but never both, so you can never observe their individual treatment effect directly. Causal inference is the science of recovering an average effect from data where half of every story is missing. Randomization solves it by design; when you cannot randomize, you solve it by assumptions you must state out loud.

1

Potential Outcomes and the Missing Half

The cleanest way to define a causal effect is to imagine two parallel worlds for each unit. In one, the unit is treated and we see Y(1); in the other, it is not and we see Y(0). The individual causal effect is Y(1) − Y(0). Reality only ever hands you one of the two columns per row.

Each unit has two potential outcomes; you observe only one customer Y(1) treated Y(0) not treated effect Ava $420 ?   (unseen) ? Ben ?   (unseen) $300 ? Cara $510 ?   (unseen) ? Dan ?   (unseen) $260 ? the grayed cells are counterfactuals: we infer their average, we never observe them

Because the individual effect is unknowable, causal inference targets an average. The average treatment effect (ATE) is the mean of Y(1) − Y(0) across the population; the ATT restricts it to those actually treated. The trap is the naive estimate: simply comparing the average outcome of the treated with the average outcome of the untreated. That equals the causal effect only when the two groups were otherwise identical, which, outside a randomized experiment, they almost never are.

2

Confounding, DAGs, and the Backdoor

A confounder is a common cause of both the treatment and the outcome. It opens a backdoor path, a non-causal route along which association flows, making the naive comparison misleading. A causal diagram (DAG) draws these dependencies as arrows and shows exactly what you must adjust for.

Confounder: adjust for X X T Y T → Y is the causal effect we want X → T → ... ← X → Y is the backdoor Collider: do NOT adjust for C T Y C controlling C opens a fake T – Y association

The rule is the backdoor criterion: to identify the effect of T on Y, adjust for a set of variables that blocks every backdoor path, and no more. Adjusting for a genuine confounder removes bias. But adjusting for a collider (a common effect of treatment and outcome) or a mediator (a variable on the causal path itself) introduces bias. This is why “controlling for everything” is not a strategy: the DAG tells you which variables to include and which to leave alone. It is also the engine behind Simpson's paradox, where an effect reverses sign once a lurking confounder is accounted for.

3

The Causal Toolkit

Once the DAG tells you what to adjust for, a family of designs does the adjusting. The gold standard breaks confounding by force; the rest are quasi-experimental tricks for when you only have observational data.

Why randomizing works: it cuts the confounder's arrow into T Observational: X -> T backdoor open X T Y Randomized: coin flip sets T X T Y no arrow into T → naive difference is unbiased
Every method rests on an untestable assumption

Adjustment methods assume no unmeasured confounders (you controlled for everything that matters). Instrumental variables assume the instrument is valid. Difference-in-differences assumes parallel trends. The data cannot prove these; they are arguments you make from domain knowledge. Honest causal work states its assumption plainly and probes how fragile the answer is if it fails, a sensitivity analysis.

4

Real-World Example: Does the Loyalty Program Cause More Spending?

A retailer launches a loyalty program and, a year later, notices enrolled customers spend far more than non-members. Did the program cause that? The companion notebook works the full observational analysis with statsmodels and scikit-learn.

📂 Dataset · causal-inference--loyalty-program.xlsx

2,000 customers, observational (nobody was randomized into the program). Columns: customer_id, prior_spend (last year, a confounder), tenure_months (a confounder), enrolled (the treatment), and spend (this year, the outcome). The data is built with a known true effect of $120 so we can see which method recovers it.

  • Confounding is visible: enrollees had a higher prior spend ($244 vs $181) and longer tenure (37 vs 28 months) before the program even existed.
  • Naive comparison: a raw difference in means says +$196, badly overstating the effect because enrollees were bigger spenders to begin with.
  • After adjustment: regression on the confounders gives +$117 (95% CI $111 to $123), and propensity weighting (IPW) about +$101, both close to the true $120 and far below the naive figure.

The lesson is the whole chapter in one number: the naive +$196 is not a smaller, noisier version of the truth, it is systematically wrong, and no amount of extra data would fix it. Only once you block the backdoor, by adjusting for the variables that drove both enrollment and spending, does the estimate collapse to the real +$117. That gap between $196 and $117 is confounding bias made concrete, and telling them apart is the entire value of causal inference.

5

Causal Inference in Machine Learning & AI

Standard machine learning is superb at prediction and silent about intervention: a churn model tells you who will leave, not whether a discount would stop them. Causal machine learning fuses the two, using flexible models to estimate effects, not just outcomes.

Where it shows upWhat it doesExamples
Uplift modeling / CATEEstimate the treatment effect per person and target the persuadable, not the already-loyalCoupon targeting, churn-save campaigns, personalized offers
Causal forests & meta-learnersMachine-learn how the effect varies across subgroups (S-, T-, X-learners)EconML, causalml, generalized random forests
Double / debiased MLUse ML for the nuisance parts and orthogonalize, giving valid effects with many covariatesDouble ML (Chernozhukov et al.), partially linear models
Off-policy evaluationEstimate how a new policy would perform from data logged under an old oneRecommenders, contextual bandits, reinforcement learning
Instrumental & deep IVRecover effects under unobserved confounding using instruments and neural first stagesDeep IV, demand estimation, pricing
Causal discoveryLearn the DAG itself from data rather than assuming itPC / GES algorithms, NOTEARS, causal representation learning
🔬 Research frontier

Causality is one of the liveliest frontiers in AI, driven by a simple ambition: to move models from prediction to intervention and reasoning about what-if. Active threads include debiased machine learning for trustworthy effect estimates at scale, causal discovery that learns structure instead of assuming it, and a growing effort to test whether large language models can reason causally or only mimic the patterns of causal language. The prize is systems that do not just forecast the world but understand how acting on it changes what comes next.

🐍

Estimate a causal effect in Python

The companion notebook loads the loyalty-program data, shows the baseline imbalance that betrays confounding, computes the misleading naive difference, then recovers the true effect three ways: regression adjustment with statsmodels, a propensity-score model with inverse-probability weighting, and a quick check that the covariates are balanced after weighting, each step with a plot.

📓 View Notebook (code & outputs) ▶ Open in Colab ⬇ View / Download on GitHub

View opens the rendered notebook instantly. Open in Colab runs it live. To run locally, install numpy, pandas, matplotlib, statsmodels, scikit-learn, and openpyxl.

🎓 Key Takeaways

  • Causation is about intervention: the effect is the gap between the two potential outcomes Y(1) and Y(0), and you only ever see one of them.
  • The naive comparison is a trap: treated-minus-untreated equals the causal effect only when the groups are otherwise identical.
  • Confounders open backdoor paths: draw the DAG, adjust for confounders to remove bias, and never adjust for colliders or mediators.
  • A toolkit, not a formula: RCTs, regression adjustment, propensity scores, difference-in-differences, instrumental variables, and regression discontinuity.
  • Every method needs an untestable assumption (no unmeasured confounders, valid instrument, parallel trends); state it and stress-test it.
  • Adjustment matters: in the example the naive +$196 collapsed to the true +$117 only after blocking the backdoor.
6

Practice Challenges

Five exercises on the loyalty-program data. Full solutions are in the companion solutions notebook.

1

Show the confounding

Compare prior_spend and tenure_months across enrolled and non-enrolled groups. Why does this imbalance bias the naive estimate upward?

Hint: df.groupby("enrolled")[[...]].mean().
2

Naive vs adjusted

Compute the naive difference in mean spend, then fit spend ~ enrolled + prior_spend + tenure_months and read the enrolled coefficient. How far apart are they?

Hint: smf.ols(...).fit().params.
3

Propensity scores

Fit a logistic model for enrollment on the two confounders and plot the propensity-score distributions for the two groups. Where do they overlap?

Hint: LogisticRegression().predict_proba.
4

Inverse-probability weighting

Use the propensity scores to compute the IPW estimate of the effect. How close is it to the regression estimate and the true $120?

Hint: weight treated by 1/p and controls by 1/(1-p).
5

Control for a collider

Invent a variable caused by both spend and enrollment, add it to the regression, and watch the estimate distort. Why is more controls not always better?

Hint: generate C = a*spend + b*enrolled + noise, then include C.
📓

Solutions notebook

All five challenges worked in code, the confounding imbalance, naive versus adjusted, propensity scores, inverse-probability weighting, and the collider trap, each with a short explanation.

📓 View Solutions ▶ Open in Colab ⬇ GitHub
7

Quiz: Test Yourself

Eight questions on potential outcomes, confounding, DAGs, and the causal toolkit. Answer them, hit Check Answers, and keep refining until you score 100%. Your progress is saved.

➡️
Up next

Causal inference asked whether an action changes an outcome. Next, we turn to outcomes that unfold over time. Survival Analysis models time until an event, a customer churns, a machine fails, a patient recovers, and uses the data that is still unfolding instead of throwing it away.