P / 02 — Causal ML · Open source

uplift-pricing Promo Targeting.

Who should actually get the discount? Causal uplift meta-learners with Qini evaluation and a policy simulator that prices the model's decisions in dollars — built on a randomized-campaign simulator with known ground-truth effects, so every claim is testable.

Causal ML S/T/X meta-learners Qini / AUUC scikit-learn Python
A B C
2.9×
Profit vs blanket campaign
0.143
Best Qini coefficient
0.90
Corr with true effect
20K
Customers simulated
01 / Context

The wrong question is "who will buy?"

A blanket promo pays the offer cost for every customer — including loyal ones who would have bought anyway (pure margin giveaway) and lost causes who won't respond either way. Uplift models estimate the causal effect of the offer per customer, so you only treat the persuadables.

The repo ships a randomized-campaign simulator that returns each customer's true treatment effect — price-sensitive and lapsed customers respond strongly, very frequent buyers show slight cannibalization. Because ground truth is known, the test suite asserts randomization balance, effect recovery, and learner ranking quality instead of taking them on faith.

02 / Results in data

The benchmark, visualised.

All charts are the actual output of uplift-pricing on the seeded 20,000-customer campaign (60/40 train/holdout, offer cost $3.00, 30% margin).

Qini curves — incremental spend captured by targeting depth

Rank customers by predicted uplift, treat the top-x%, measure incremental outcome vs the randomized control. The further above the random-targeting diagonal, the better the ranking.

holdout n=8,000 · diagonal = random targeting

Incremental profit by targeting depth — where theory meets P&L

Profit of treating the top-x% by model score, priced against ground truth. The curve peaks where marginal uplift × margin = offer cost — treat ~55% of customers, earn 2.9× the blanket campaign.

offer cost $3.00 · margin 30% · dashed line = treat-everyone baseline ($2,199)

Learner quality

Qini coefficient and correlation with the simulator's true per-customer effect, per meta-learner.

S-learner wins here; X-learner closes the gap when arms are imbalanced
pip install -e ".[dev]" && pytest
15 passed in 19.02s
uplift-pricing
best policy: model_top_50pct -> $6,360 vs blanket campaign $2,199
03 / Design

How it works.

  • Three meta-learners (S, T, X) behind one fit / predict_uplift interface, built on scikit-learn's HistGradientBoosting — swap in any regressor.
  • Qini, not accuracy: uplift models are consumed as rankings; the Qini coefficient measures incremental outcome captured when targeting top-k vs random.
  • Profit is the decision metric: the policy module converts scores into a targeting rule and sweeps the treated fraction in dollars.
  • Tests prove the claims: randomization balance across arms, observed ATE ≈ true ATE, every learner's correlation with truth > 0.5, and targeted policy beats blanket — all enforced in CI.