Home Marketing Predictions Artikel 3
Teil 3 Generative AI

Click-Through-Rate (CTR) Prediction

Bild: KI-generiert mit Beuys


Click-Through-Rate (CTR) Prediction

CTR-Prediction ist das Paradebeispiel eines stark imbalanced Klassifikationsproblems. Class-Weights, Kalibrierung und Feature-Hashing für hochkardinale Werbedaten – und warum Accuracy hier irreführend ist und ein Calibration-Plot mehr verrät als jede AUC.


1. Das Problem: Wenn 1 % Performance über Millionen entscheidet

Im Display-Advertising liegen echte Click-Through-Rates oft zwischen 0.5 % und 3 %. Ein „Modell", das immer „kein Klick" vorhersagt, erreicht über 97 % Accuracy – und ist trotzdem unbrauchbar. Drei Konsequenzen ergeben sich daraus:

  1. Accuracy ist als Metrik ungeeignet. PR-AUC, Log-Loss und Calibration sind die ehrlicheren Maße.
  2. Kalibrierte Wahrscheinlichkeiten sind Pflicht, nicht Kür. Bidding-Systeme multiplizieren P(Klick) × Wert(Klick). Ein um Faktor 2 verzerrter Wahrscheinlichkeitswert verbrennt direkt Budget.
  3. Hochkardinale Features (User-ID, Ad-ID, Domain) brauchen spezielle Behandlung – OneHot-Encoding würde Millionen Spalten erzeugen.

2. Class Imbalance: Was tatsächlich hilft

❌ Naive Lösung: Mehr Daten, gleiche Loss

Mehr Trainingsdaten allein lösen das Problem nicht. Bei 99 % Negativen lernt das Modell weiterhin primär das Negativ-Muster.

✅ Drei wirksame Hebel

Hebel Effekt Kosten
class_weight="balanced" Reweighting der Loss-Funktion Keine zusätzlichen Daten, leichte Verzerrung der Wahrscheinlichkeiten
Under-Sampling der Negativen Schnelleres Training, stärkeres Positiv-Signal Wahrscheinlichkeiten müssen rekalibriert werden
CalibratedClassifierCV Bringt Wahrscheinlichkeiten zurück in den realen Range Zusätzlicher CV-Pass

Quick-Check: Warum ist Accuracy bei CTR-Prediction irreführend?

3. Feature-Hashing für hochkardinale Kategorien

User-ID, Ad-ID, Publisher-Domain – jedes dieser Felder hat potenziell Millionen distinkter Werte. OneHotEncoder ist nicht praktikabel. Zwei etablierte Alternativen:

Quick-Check: Welcher Effekt ist beim Feature-Hashing unvermeidlich, aber meist akzeptabel?

4. End-to-End: Imbalanced CTR mit Kalibrierung

Der folgende Block trainiert eine LogisticRegression mit Class-Weighting und vergleicht sie mit der kalibrierten Variante. Zur Diagnose wird ein Reliability-Diagram gezeichnet: Es trägt die vorhergesagte Wahrscheinlichkeit gegen die tatsächlich beobachtete Frequenz auf. Ein perfekt kalibriertes Modell liegt auf der Diagonale.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.calibration import CalibratedClassifierCV, calibration_curve
from sklearn.metrics import average_precision_score, log_loss
from sklearn.model_selection import train_test_split

rng = np.random.default_rng(1)
n = 10000
X = rng.normal(size=(n, 6))
# CTR ~ 2 % – stark imbalanced
logit = X[:, 0] + 0.5 * X[:, 1] - 4.0
p_true = 1 / (1 + np.exp(-logit))
y = (rng.random(n) < p_true).astype(int)
print(f"Positiv-Rate: {y.mean():.3f}")

X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)

# Variante A: LogReg mit class_weight="balanced" (verzerrte Wahrscheinlichkeiten)
base = LogisticRegression(class_weight="balanced", max_iter=1000).fit(X_tr, y_tr)
p_base = base.predict_proba(X_te)[:, 1]

# Variante B: Dieselbe LogReg, aber kalibriert
cal = CalibratedClassifierCV(
    LogisticRegression(class_weight="balanced", max_iter=1000),
    method="isotonic", cv=5,
).fit(X_tr, y_tr)
p_cal = cal.predict_proba(X_te)[:, 1]

print(f"PR-AUC  base={average_precision_score(y_te, p_base):.3f}  cal={average_precision_score(y_te, p_cal):.3f}")
print(f"LogLoss base={log_loss(y_te, p_base):.4f}  cal={log_loss(y_te, p_cal):.4f}")

# Reliability-Diagram
frac_base, mean_base = calibration_curve(y_te, p_base, n_bins=10, strategy="quantile")
frac_cal,  mean_cal  = calibration_curve(y_te, p_cal,  n_bins=10, strategy="quantile")

fig, ax = plt.subplots(figsize=(6, 6))
ax.plot([0, 1], [0, 1], "k--", label="Perfekt kalibriert")
ax.plot(mean_base, frac_base, "o-", label="LogReg balanced (unkalibriert)")
ax.plot(mean_cal,  frac_cal,  "s-", label="+ Isotonic Calibration")
ax.set_xlabel("Vorhergesagte Wahrscheinlichkeit")
ax.set_ylabel("Tatsächliche Frequenz")
ax.set_title("Reliability-Diagram (CTR-Modell)")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.show()

Die unkalibrierte Variante mit class_weight="balanced" liefert oft die gleiche Ranking-Qualität (PR-AUC) wie die kalibrierte, weicht aber im Reliability-Diagram deutlich von der Diagonale ab. Für reine Sortier-Aufgaben (Top-N-Ranking) genügt das. Sobald aber Wahrscheinlichkeiten als Zahlen in eine Folgeentscheidung eingehen – Real-Time-Bidding, erwartete Konversion, Budget-Allokation – muss kalibriert werden.

Quick-Check: Wofür dient `CalibratedClassifierCV`?

5. Offline- vs. Online-Evaluierung

Offline-Metriken (PR-AUC, Log-Loss, Reliability) sind notwendig, aber nicht hinreichend. Drei zusätzliche Schritte sind in produktiven CTR-Systemen Standard:

6. Abschluss-Quiz

Welche Metrik eignet sich am besten zur Bewertung eines CTR-Modells mit ~1 % Positiv-Rate?

Ein Reliability-Diagram zeigt, dass das Modell bei vorhergesagtem p=0.1 in Wirklichkeit nur 0.03 Klickrate hat. Was bedeutet das?

Warum ist ein chronologischer (Time-based) Train/Test-Split bei CTR-Daten oft ehrlicher als ein random Split?

7. Weiterführend

Quellen

📄 Als PDF