Условие
Модель XGBoost даёт predict_proba. ROC AUC = 0.85, но при p>0.7 реально положительных только 50%. Что делать?
Решение
Подход
predict_proba от древесных моделей часто mis-calibrated — порядок верный (AUC высокий), но численные значения не отражают вероятностей. Решение — post-hoc calibration.
Методы
- Platt scaling (logistic):
p_cal = σ(a·logit(p_raw) + b). Параметры a,b обучаются на holdout. Хорошо для S-shaped distortion. - Isotonic regression: непараметрический, монотонная функция. Требует больше данных (n > 1000 на holdout).
- Beta calibration: гибче чем Platt.
Метрики калибровки
- Brier score:
(1/n) Σ (p − y)². Composite — точность + калибровка. - ECE (Expected Calibration Error): разбиваем p на bins, в каждом bin сравниваем avg(p) с avg(y).
import numpy as np
def expected_calibration_error(y_true, y_prob, n_bins=10):
bins = np.linspace(0, 1, n_bins+1)
ece = 0
for i in range(n_bins):
mask = (y_prob > bins[i]) & (y_prob <= bins[i+1])
if mask.sum() > 0:
avg_pred = y_prob[mask].mean()
avg_true = y_true[mask].mean()
ece += abs(avg_pred - avg_true) * mask.sum() / len(y_true)
return eceРеализация Platt / isotonic
from sklearn.calibration import CalibratedClassifierCV
# cv='prefit' если базовая модель уже обучена
calibrated = CalibratedClassifierCV(base_estimator=xgb_model, method='isotonic', cv='prefit')
calibrated.fit(X_holdout, y_holdout)
p_cal = calibrated.predict_proba(X_test)[:,1]Или вручную:
from sklearn.isotonic import IsotonicRegression
iso = IsotonicRegression(out_of_bounds='clip')
iso.fit(p_raw_holdout, y_holdout)
p_cal = iso.transform(p_raw_test)Calibration plot
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt
prob_true, prob_pred = calibration_curve(y_test, p_raw, n_bins=10)
plt.plot(prob_pred, prob_true, marker='o')
plt.plot([0,1], [0,1], '--') # идеалПодводные камни
- Calibration set отдельный от train: иначе калибратор обучается на overfitted predictions.
- Isotonic с малым n (<500) overfit, особенно в хвостах. Используйте Platt.
- Модели уже calibrated «из коробки»: LogisticRegression, NaiveBayes (приблизительно). RF/XGB — часто нет.
- Калибровка не улучшает AUC, только Brier / ECE / logloss. Если бизнес смотрит на AUC, эффекта не увидит, но решения по threshold станут лучше.
- На imbalanced data ROC AUC обманчив; калибровка vs uncalibrated — оба могут быть okay по AUC, но один из них врёт в порогах.
Эталонный ответ
Mis-calibrated predict_proba лечится post-hoc: Platt scaling (parametric) или isotonic regression (нонпараметрический). Обучается на отдельном holdout. Метрики калибровки — Brier score, ECE, calibration plot. Не улучшает AUC, но делает proba осмысленными для бизнес-порогов.