search_ads_recsys / 27 · causal inference & uplift lesson 27 / 39

Causal inference & uplift modeling

Your ranker predicts P(click | shown). Your business wants to know whether showing this notification, ad, or coupon actually changed what the user did — versus doing nothing. Those are different questions, and the gap between them is the entire lesson. Predicting an outcome is not the same as estimating the effect of an intervention.

The gap: prediction vs intervention

Every model so far in this series fits a conditional expectation — E[Y | X], the click rate of items given they were shown. That is a predictive quantity, and for picking the top item at a fixed slot it is usually enough (lesson 08 · Evaluation defends exactly that). But a huge class of decisions is not "which item is best" — it is "does doing this thing change behavior at all?" Send the push or stay silent. Spend the coupon or save it. Re-rank this feed or leave the default. These are interventions, and the quantity you need is a counterfactual contrast: behavior under treatment minus behavior without it.

The trap is that a high-P(convert) user and a high-uplift user are often different people. The user who would have bought anyway scores high on your conversion model and is exactly the user a coupon wastes money on. The whole field of causal inference and uplift modeling exists to stop you from confusing the two.

The one-line summary you should be able to give
A ranker estimates E[Y | X, shown] — a prediction. A decision about an intervention needs E[Y(1) - Y(0) | X] — a causal effect, the difference between two potential outcomes you can never both observe. Uplift modeling is the discipline of targeting the effect, not the outcome.

Potential outcomes — the Rubin framework

Fix a unit (a user). Define two potential outcomes: Y(1) is what happens if we treat them (send the push), Y(0) is what happens if we don't. The individual treatment effect is

τ_i = Y_i(1) − Y_i(0).

Here is the fundamental problem of causal inference: for any single user you observe at most one of Y_i(1) and Y_i(0) — you either sent the push or you didn't; the other is a counterfactual that never happened. τ_i is never directly observable. Causal inference is the art of recovering averages of these effects despite never seeing a single one.

Y(1) Y(0) τ = Y(1) − Y(0) user A ┌─────────┐ ┌─────────────┐ (treated)│ 1 obs │ │ ? missing │ unknown — never both └─────────┘ └─────────────┘ user B ┌─────────┐ ┌─────────────┐ (control)│ ? missng│ │ 0 obs │ unknown — never both └─────────┘ └─────────────┘ the "?" cells are the counterfactuals. We never fill them in; we only estimate population averages over them.

So we step down from the individual to estimable averages:

The ATE answers "should the campaign exist." The CATE answers "whom do I target," which is the question that actually moves money. The rest of this lesson is two halves: how to get an unbiased ATE/CATE when you can randomize, and how to approximate one when you can't.

Why the A/B test is the gold standard

Randomization is the one move that makes causal inference trivial. If a coin decides who is treated, then treatment assignment T is independent of every confounder — observed or not — so the treated and control groups are statistically identical except for the treatment. The naive difference of group means is then unbiased for the ATE:

ÂTE = Ȳ_treated − Ȳ_control.

This is exactly the A/B test from lesson 08 · Evaluation, now read through a causal lens: the experiment manufactures the counterfactual by holding out a randomized control. No randomization → confounding → the difference of means estimates correlation, not effect.

When you genuinely cannot run the A/B test
The gold standard is sometimes off the table: ethics (you cannot randomly deny a safety notification or a fraud block), cost / scale (a holdout on a flagship feature is real revenue forgone), already shipped (the intervention rolled out to everyone last quarter — there is no control group to construct), and slow outcomes (the metric is 90-day retention or lifetime value; you cannot wait a quarter per iteration). When the experiment is impossible, you fall back to observational causal methods — and you inherit their assumptions, every one of which is a way to be silently wrong.

Uplift = targeting the effect, not the outcome

Cross two binary facts about a user — would they convert if treated? would they convert if not treated? — and you get the four canonical response types. This 2×2 is the most important picture in the lesson:

WOULD CONVERT IF NOT TREATED (Y(0)) no yes ┌────────────────────────┬────────────────────────┐ WOULD yes│ PERSUADABLES │ SURE THINGS │ CONVERT │ τ = +1 │ τ = 0 │ IF TREATED │ convert ONLY because │ convert anyway — │ (Y(1)) │ you treated → TARGET │ treating wastes spend │ ├────────────────────────┼────────────────────────┤ no │ LOST CAUSES │ SLEEPING DOGS │ │ τ = 0 │ τ = −1 │ │ never convert either │ treating ANNOYS them │ │ way → wasted spend │ → they churn → AVOID │ └────────────────────────┴────────────────────────┘

The punchline: ranking by predicted P(convert) systematically targets the sure things and ignores the persuadables. A user with 90% baseline conversion has almost no headroom — treating them can only move them a few points. A user at 30% baseline who jumps to 70% under treatment has a +40-point uplift and is invisible to a conversion ranker. Uplift modeling reorders your targeting around τ(x), not P(Y=1 | x). The interactive below makes the budget consequences concrete.

CATE estimators — the meta-learners

Given randomized (or unconfounded) data with features X, treatment T, outcome Y, how do you estimate τ(x)? The meta-learners are recipes that wrap any off-the-shelf regressor (a "base learner") into a CATE estimator. Three you must know:

LearnerRecipeTrade-off
S-learner (single) Train one model μ(x, t) on all data with treatment t as just another feature. Estimate τ̂(x) = μ(x,1) − μ(x,0). Lowest variance, simplest. But if the learner regularizes t away (one feature among hundreds), it predicts τ ≈ 0 everywhere — biased toward no effect. Dangerous when the true uplift is small.
T-learner (two) Train two separate models: μ_1(x) on the treated, μ_0(x) on the control. τ̂(x) = μ_1(x) − μ_0(x). Cannot regularize the effect away — treatment cannot be ignored because it defines the split. But each model sees half the data, and the two error surfaces don't cancel → higher variance, especially when groups are imbalanced.
X-learner (cross) Fit T-learner models, then impute each unit's individual effect using the other group's model and regress on those imputed effects, weighting by the propensity e(x). Best of both when treatment groups are very imbalanced (e.g. few treated): borrows strength from the large group to estimate effects in the small one. More moving parts, more to tune.

The X-learner recipe in full, because interviewers ask for it: (1) fit μ_0, μ_1 as in the T-learner. (2) Impute the treated units' effects as D_1 = Y - μ_0(X) and the control units' as D_0 = μ_1(X) - Y. (3) Regress D_1 on X to get τ_1(x), and D_0 on X to get τ_0(x). (4) Combine with the propensity as a weight: τ̂(x) = e(x) τ_0(x) + (1 − e(x)) τ_1(x). When treated units are rare, e(x) is small, so the estimate leans on τ_1 — the effects imputed for the many control units — which is exactly the strength-borrowing you want.

Causal forests — honesty

A causal forest is a random forest whose splits maximize treatment-effect heterogeneity rather than outcome purity — each split tries to separate high-uplift from low-uplift users. Its key trick is honest splitting: one subsample decides the tree structure (where to split), a disjoint subsample estimates the effect inside each leaf. Reusing the same data for both would let the tree overfit splits to noise and then "confirm" that noise in the leaf estimate. Honesty buys valid confidence intervals on τ(x) — rare and precious in CATE estimation, since you can never check against a ground-truth ITE.

You cannot score uplift with accuracy or AUC
Every model elsewhere in this series is graded against an observed label. Uplift has no observed label — the true ITE τ_i is the one thing the fundamental problem guarantees you never see. So "accuracy of the uplift prediction" is undefined. Evaluating uplift with a standard classification metric is a classic, disqualifying mistake. You need a metric built on group contrasts instead.

Evaluating uplift — Qini and AUUC

The fix: don't grade per-user, grade the ranking. Sort the population by predicted uplift descending. Walk down the list; at each depth, compute the actual outcome gap between treated and control units among those targeted so far. A good uplift model puts the persuadables first, so the cumulative gain rises steeply early and the curve bows above the random-targeting diagonal.

A flat or below-diagonal Qini curve means your "uplift" model is no better than random targeting — or worse, is sorting sure things to the top.

Observational causal methods — when there is no experiment

No randomization means treatment is confounded: the users who got treated differ systematically from those who didn't, in ways that also drive the outcome. Every method below is a different strategy for breaking that confounding, and each rests on one load-bearing assumption that, if false, silently invalidates the whole estimate. Know the assumption better than the method.

Two assumptions underlie the entire observational program and deserve naming up front:

MethodIdeaThe one assumption that sinks it if violated
Propensity-score matching (PSM) Estimate e(x) = P(T=1 | x), then pair each treated unit with a control unit of nearly equal propensity and compare. Collapses high-dim matching to a 1-D score. Unconfoundedness — you can only match on observed covariates. A hidden confounder you didn't put in e(x) leaves the matched pairs still unbalanced, and no amount of matching fixes it.
Inverse propensity weighting (IPW) Reweight each unit by 1/e(x) (treated) or 1/(1-e(x)) (control) to synthesize a pseudo-population in which treatment is independent of X. Same propensity machinery as lesson 07 · Bias & debiasingthere it debiases logged clicks for ranking; here it debiases treatment groups for an effect estimate. Overlap — a unit with e(x) → 0 gets weight → ∞, so a handful of near-deterministic units explode the variance (exactly the IPS variance blow-up from lesson 07; doubly-robust estimators are the shared fix).
Difference-in-differences (DID) A group gets treated at time t, another doesn't. Compare the treated group's change (after − before) to the control group's change — differencing out any fixed group gap and any common time trend. Parallel trends — absent treatment, both groups would have moved in parallel. Untestable for the post period; if the treated group was already on a different trajectory, you attribute that divergence to the treatment.
Synthetic control When you have one treated unit (one market, one region), build a weighted blend of untreated units that tracks the treated unit's pre-period series, then read the gap post-treatment as the effect. Good pre-period fit from a convex donor pool — the synthetic must match the treated unit before treatment using only untreated donors. Poor pre-fit, or no donor combination that reproduces the treated trajectory, and the post-period gap is meaningless.
Instrumental variables (IV) Find an instrument Z that shifts treatment but affects the outcome only through treatment. Use the Z-induced variation in T as quasi-random (two-stage least squares). Exclusion restrictionZ must have no direct path to Y except via T. Untestable, and almost any plausible instrument has some back-channel to the outcome, which biases the estimate.

The DID estimator is worth seeing as a clean 2×2, because it is the one observational design you can sketch on a whiteboard in ten seconds:

τ̂_DID = (Ȳ_(treat,after) − Ȳ_(treat,before)) − (Ȳ_(ctrl,after) − Ȳ_(ctrl,before)).

beforeafterchange
treated group1018+8
control group1215+3
DID effect+8 − 3 = +5

The control group's +3 is the "what would have happened anyway" trend; subtracting it leaves +5 as the treatment's incremental effect — if parallel trends holds. Note the IPW estimator is the same inverse-propensity weight you met in lesson 07, just summed into an effect rather than a loss:

τ̂_IPW = (1/n) Σ_i [ (T_i Y_i)/(e(x_i)) − ((1 − T_i) Y_i)/(1 − e(x_i)) ].

The confounder that eats your launch
You ship a new "premium" badge to sellers who opt in, observe their sales jump 20%, and credit the badge. But sellers who opt in are the motivated, growing ones — the same drive that made them opt in is independently lifting their sales. That's the unobserved confounder; unconfoundedness is violated and PSM/IPW on observed features won't save you, because the confounder is the unmeasured "seller ambition." This is why a randomized holdout, when feasible, beats any observational estimate: it severs the link between who-gets-treated and who-would-succeed-anyway by construction.

The recsys / ads application

This is where uplift earns its keep — every interruptive intervention has a cost and a backfire mode:

Uplift, bandits, and RL are one family
Uplift estimates the effect of a one-shot intervention from a fixed log. A multi-armed bandit (lesson 15 · Cold start) actively randomizes to learn effects online while minimizing regret — randomization is its built-in, continuous A/B test. Reinforcement learning (lesson 16 · Reinforcement learning) generalizes to sequences of interventions optimizing long-run reward. They share one spine: choosing actions by their causal effect on an outcome, not by a passive prediction. When you can randomize online, prefer a bandit; when you're stuck with a log, you're doing observational uplift; when the effect compounds over a session, it's RL.

Interactive · uplift targeting vs the naive ranker

A population of 10,000 users splits into the four response types in tunable proportions. Each treatment costs money; each incremental conversion is worth something. Compare two targeting strategies at a chosen budget: target by predicted P(convert) (the naive conversion ranker — it loves sure things) versus target by predicted uplift (persuadables first). Watch net profit, wasted spend on sure things, and annoyed sleeping dogs diverge.

Who should you actually treat?
The naive ranker treats whoever is most likely to convert — which front-loads sure things (they convert anyway, so you pay for nothing) and, once those run out, starts hitting sleeping dogs. Uplift targeting treats persuadables first and never touches sleeping dogs until forced. Push the budget up and watch the naive strategy's profit roll over as it scrapes the bottom of the barrel.
net profit — naive P(convert)
net profit — uplift targeting
profit left on table by naive
lost causes (always wasted)
Reading
Adjust the sliders to see how the two strategies spend the budget.

Interview prompts you should be ready for

  1. "What's the difference between a model that predicts conversion and one that estimates uplift, and why does it matter for a coupon budget?" (Prediction estimates E[Y | X, treated]; uplift estimates E[Y(1) − Y(0) | X]. Ranking by predicted conversion targets sure things — users who'd convert anyway — so the coupon buys nothing. Uplift targets persuadables, the only quadrant with positive ROI. Name the four-quadrant picture.)
  2. "State the fundamental problem of causal inference and how randomization gets around it." (You observe at most one of Y(1), Y(0) per unit, so the individual effect is never seen. Randomization makes T independent of all confounders, so the difference of treated and control group means is unbiased for the ATE — you recover an average over the unobservable counterfactuals.)
  3. "Compare S-, T-, and X-learners." (S: one model with treatment as a feature — low variance but can regularize the effect to ~0. T: separate treated/control models — can't ignore treatment but higher variance, each sees half the data. X: impute individual effects via the other group's model and reweight by propensity — best when treatment groups are very imbalanced, at the cost of complexity.)
  4. "You can't run an A/B test because the feature already shipped to everyone. How do you estimate its causal effect?" (No control group, so reach for a quasi-experiment: difference-in-differences against an untreated segment/geo (needs parallel trends), or synthetic control if there's a single treated unit and a good donor pool. State the load-bearing assumption and how you'd probe it — e.g., a pre-period placebo test for parallel trends.)
  5. "How do you evaluate an uplift model offline, and why can't you use AUC?" (The true ITE is never observed, so there's no per-user label for accuracy/AUC. Use the uplift/Qini curve: sort by predicted uplift, plot cumulative treated-minus-control gain vs fraction targeted; AUUC summarizes it. A below-diagonal curve means you're no better than random — or are sorting sure things to the top.)
  6. "PSM and IPW both use the propensity score — how do they differ, and which assumption is fatal to each?" (PSM matches treated to control units of equal propensity; IPW reweights by 1/e(x) to synthesize a balanced pseudo-population. PSM is sunk by unconfoundedness — you can only match on observed covariates. IPW is sunk by overlap — e(x)→0 sends weights to infinity and variance explodes. Same propensity as lesson 07's IPS; doubly-robust is the shared variance fix.)
  7. "When would you choose a bandit over an uplift model over plain RL?" (Bandit when you can randomize online and want to learn effects while bounding regret — it's a continuous built-in experiment. Observational uplift when you're stuck with a fixed log and can't randomize. RL when the intervention's effect compounds over a sequence and you're optimizing long-run reward, not a one-shot outcome. All three pick actions by causal effect, not passive prediction.)
Takeaway
A ranker predicts outcomes; a business decides interventions — and the two diverge because the fundamental problem of causal inference hides the per-user effect τ_i = Y_i(1) − Y_i(0). The fix is to estimate averages: ATE for "should it exist," CATE/uplift for "whom to target." Rank by τ(x), not P(Y=1|x), or you'll spend your whole budget on sure things and poke sleeping dogs into churning. Randomize when you can — an A/B test manufactures the counterfactual and makes the estimate trivially unbiased. When you can't, fall back to PSM/IPW (unconfoundedness + overlap), DID (parallel trends), synthetic control (pre-period fit), or IV (exclusion restriction) — and remember that for every one, the assumption is the estimate. Grade uplift with Qini/AUUC, never accuracy. And when you can act online, a bandit is just uplift estimation that randomizes for itself.