Statistische Tests beantworten „Ist der Unterschied real?", Uplift-Modelle beantworten „Bei wem wirkt die Kampagne?". Zwei verwandte, aber grundsätzlich verschiedene Fragen – mit zwei verschiedenen Methoden-Familien und einem from-scratch-Two-Model-Beispiel inklusive Qini-Curve.
1. Zwei verschiedene Fragen, zwei verschiedene Werkzeuge
Wer nur Conversions vorhersagt, optimiert die falsche Größe: ein Conversion-Modell schickt Coupons an Menschen, die ohnehin gekauft hätten. Die saubere Trennung sieht so aus:
| Frage | Werkzeug | Liefert |
|---|---|---|
| Ist die durchschnittliche Wirkung der Kampagne signifikant? | A/B-Test, Bootstrap-CI | Eine Zahl: durchschnittlicher Treatment-Effekt (ATE) |
| Bei welchen Individuen wirkt die Kampagne? | Uplift-Modelling | Individuelle Schätzung des Treatment-Effekts (CATE) |
Beide Methoden teilen denselben Datentyp: eine randomisierte Stichprobe mit Treatment-Indikator T ∈ {0,1} und Outcome Y ∈ {0,1}.
2. A/B-Tests: Was wirklich signifikant ist
❌ Pitfall: Peeking
Mehrfaches Auswerten während der Laufzeit inflationiert die False-Positive-Rate. Bei 10 Zwischenchecks à α=5 % liegt die Wahrscheinlichkeit eines falschen Treffers schnell bei >30 %.
✅ Saubere Praxis
- Stichprobengröße vorab aus Power-Berechnung bestimmen.
- Auswertung erst am vorab festgelegten Endpunkt.
- Bootstrap-Confidence-Intervalle als robuste Alternative zu t-Tests (keine Normalverteilungs-Annahme).
Quick-Check: Was bedeutet 'Peeking' in A/B-Tests und warum ist es problematisch?
3. Uplift-Modelling: Die vier Segmente
Jedes Individuum lässt sich konzeptuell einem von vier Segmenten zuordnen:
| Segment | Y(T=0) | Y(T=1) | Kampagnen-Strategie |
|---|---|---|---|
| Persuadables | 0 | 1 | Anzeigen – hier liegt der ROI |
| Sure Things | 1 | 1 | Nicht anzeigen – verschwendetes Budget |
| Lost Causes | 0 | 0 | Nicht anzeigen – chancenlos |
| Do-Not-Disturb | 1 | 0 | Nicht anzeigen – schädlich! |
Das Kernproblem: Für jedes Individuum beobachten wir nur eine der beiden Welten (Y(T=0) oder Y(T=1)), nie beide. Uplift-Modelle schätzen den individuellen Treatment-Effekt aus randomisierten Daten.
Quick-Check: Welche Personengruppe wollen wir mit Uplift-Modellen primär ansprechen?
4. Two-Model-Approach: From-scratch mit Qini-Curve
Der einfachste Uplift-Ansatz trainiert zwei separate Modelle (eines auf der Treatment-, eines auf der Control-Gruppe) und nimmt die Differenz der Wahrscheinlichkeiten als Uplift-Schätzung. Zur Evaluation wird die Qini-Curve verwendet: Sie trägt die kumulierte inkrementelle Conversion gegen den Anteil der gerankten Population auf.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
rng = np.random.default_rng(2)
n = 6000
X = rng.normal(size=(n, 4))
T = rng.integers(0, 2, n) # randomisiertes Treatment
# Heterogener Treatment-Effekt: Wirkung nur bei X[:,1] > 0
p_ctrl = 1 / (1 + np.exp(-(0.5 * X[:, 0] - 1.0))) # Basisrate ~ 25 %
uplift_true = 0.25 * (X[:, 1] > 0) # echter CATE
p = np.clip(p_ctrl + T * uplift_true, 0, 1)
y = (rng.random(n) < p).astype(int)
X_tr, X_te, T_tr, T_te, y_tr, y_te = train_test_split(
X, T, y, test_size=0.4, random_state=0,
)
# Two-Model-Approach: separate Modelle für T=0 und T=1
m_t = LogisticRegression(max_iter=1000).fit(X_tr[T_tr == 1], y_tr[T_tr == 1])
m_c = LogisticRegression(max_iter=1000).fit(X_tr[T_tr == 0], y_tr[T_tr == 0])
uplift_hat = m_t.predict_proba(X_te)[:, 1] - m_c.predict_proba(X_te)[:, 1]
print(f"Geschätztes Uplift-Mittel: {uplift_hat.mean():+.3f}")
print(f"Echtes Uplift-Mittel im Test: {(0.25 * (X_te[:, 1] > 0)).mean():+.3f}")
# Qini-Curve: Population nach uplift_hat absteigend sortieren,
# kumulative inkrementelle Conversions plotten.
order = np.argsort(-uplift_hat)
y_sorted = y_te[order]
T_sorted = T_te[order]
# Kumulierte Conversions in Treatment und Control, skaliert auf gleiche Größe
cum_t = np.cumsum(y_sorted * (T_sorted == 1))
cum_c = np.cumsum(y_sorted * (T_sorted == 0))
n_t = np.cumsum(T_sorted == 1).clip(min=1)
n_c = np.cumsum(T_sorted == 0).clip(min=1)
# Inkrement = T-Rate − C-Rate, skaliert auf die Population
incremental = cum_t - cum_c * (n_t / n_c)
share = np.arange(1, len(y_te) + 1) / len(y_te)
# Zufalls-Baseline (gerade Linie zum Endwert)
random_line = share * incremental[-1]
fig, ax = plt.subplots(figsize=(7, 5))
ax.plot(share, incremental, label="Two-Model Uplift")
ax.plot(share, random_line, "k--", label="Zufalls-Targeting")
ax.set_xlabel("Anteil der adressierten Population (sortiert nach Uplift-Score)")
ax.set_ylabel("Kumulierte inkrementelle Conversions")
ax.set_title("Qini-Curve")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.show()
# Qini-Score: Fläche zwischen Modell-Kurve und Zufalls-Linie
qini_score = np.trapz(incremental - random_line, share)
print(f"Qini-Score (höher = besser): {qini_score:.3f}")
Die Qini-Curve liegt für ein nützliches Uplift-Modell oberhalb der Zufalls-Linie. Je größer die Fläche zwischen den Kurven (Qini-Score), desto besser unterscheidet das Modell Persuadables von den übrigen Segmenten. Der Knick am Ende ist normal: Wenn man auch noch die unteren 30–40 % der Population adressiert, sinkt der inkrementelle Effekt – dort sitzen Sure Things, Lost Causes und Do-Not-Disturb.
Quick-Check: Was zeigt die Qini-Curve?
5. Diskussion: Wann Two-Model und wann etwas Besseres?
Two-Model ist die einfachste, aber nicht die effizienteste Methode:
- Vorteil: Jede sklearn-kompatible Schätzfunktion einsetzbar; transparent und debugbar.
- Nachteil: Doppelt geschätztes Rauschen – beide Modelle haben eigene Fehler, die in der Differenz nicht weggehen.
- Bessere Alternativen für Produktion: Class Transformation (ein Modell, transformiertes Label), Uplift-Trees (Splits maximieren Uplift statt Reinheit), X-Learner / R-Learner (zweistufige Meta-Learner).
Praktische Heuristik: Beim ersten Uplift-Projekt mit Two-Model starten, Qini-Curve gegen Zufall validieren. Erst wenn der ROI das rechtfertigt, in komplexere Schätzer investieren.
6. Abschluss-Quiz
Worin unterscheidet sich Uplift-Modelling von gewöhnlicher Response-Prediction?
Welche Voraussetzung müssen die Trainingsdaten für Uplift-Modelle erfüllen?
Welches Segment ist für die Kampagne *schädlich*, wenn es angesprochen wird?
7. Weiterführend
- Nächster Artikel: Sentiment & Content-Insights mit kleinen LLMs (Artikel 05 dieser Serie).
- Libraries:
scikit-uplift,causalml,econml(Microsoft). - Künzel et al. (2019), Metalearners for estimating heterogeneous treatment effects using machine learning.
Quellen
- Machine Learning with PyTorch and Scikit-Learn (Sebastian Raschka et al.) – Kapitel zu Modellbewertung.
- Radcliffe & Surry (2011), Real-World Uplift Modelling with Significance-Based Uplift Trees.