AI Hints
Home›Data Science Tutorial›Advanced Causal Thinking
Data Science · Lesson 44 of 101

Uplift Modelling

Who should get the offer?.

⏱ 2 min read▶ Video at 1:15:13🎓 Free
Watch this lesson in the Data Science courseWatch on YouTube ↗Full Data Science course

A company built a model to find customers who are likely to leave, and it sent them all a discount. Churn went up. Why? Some had forgotten that they were subscribed, and the email reminded them. Don't target people who are likely to leave. Target people whose behaviour you can change.

Uplift Modelling
From the video: Uplift Modelling
  • Find likely leavers, send offers
  • Churn went up
  • Target those you can change

Four kinds of customer

Picture four groups. Persuadables stay only if you act. Those are your target. Sure things stay anyway, so the offer's wasted. Lost causes will leave whatever you do. And sleeping dogs leave because you contacted them, so leave those alone. A normal model can't separate them. Uplift modelling tries to.

Two models

We need data from a randomised test. Then we train two models. One learns from people who got the offer, and the other from people who didn't. The difference between their predictions is the uplift for each person. In this simulation, the offer helps only customers who visit rarely. Run it. On average, it lowers churn by about seven points. But look at the split. Low visitors see a large effect, and high visitors hardly any. So send it to the first group, and keep the discount money from the second.

uplift.pypython
import numpy as np
import pandas as pd
from sklearn.ensemble import HistGradientBoostingClassifier as Model

rng = np.random.default_rng(0)
n = 20000
visits = rng.gamma(2, 2, n)
offer = rng.integers(0, 2, n)
base = 0.35 - 0.02 * visits.clip(0, 12)
effect = np.where(visits < 4, -0.12, 0.0)
leave = rng.random(n) < (base + effect * offer).clip(.01, .99)
X = visits.reshape(-1, 1)

a = Model(max_iter=60).fit(X[offer == 1], leave[offer == 1])
b = Model(max_iter=60).fit(X[offer == 0], leave[offer == 0])
uplift = a.predict_proba(X)[:, 1] - b.predict_proba(X)[:, 1]

print("Average effect of the offer:", round(uplift.mean(), 3))
for name, mask in [("Low visits", visits < 4), ("High visits", visits >= 4)]:
    print(f"{name:<12} {uplift[mask].mean():+.3f}")
Output
Average effect of the offer: -0.067
Low visits   -0.103
High visits  -0.016

Summary

Target people that you can change, not just people who are at risk. You've now learned advanced causal methods that most analysts never reach. Next, let's return to forecasting, and test forecasts properly.

Key takeaways
  • Four kinds of customer
  • Train two models
  • Target the persuadable
Next up: Backtesting Forecasts — one split isn't enough