趋近智
梯度提升模型通常根据AUC或F1分数等指标,能获得较高的预测准确性,但它们在分类任务中的原始输出分数可能不直接代表真实的概率。例如,模型预测某个类别得分为0.9,并不必然表示该实例属于该类别的客观概率就是90%。优化过程,特别是使用对数损失等损失函数时,会倾向于将分数推向0和1以提高区分度,但这可能会扭曲概率解释。当实际的概率估计对于决策、风险评估或模型集成等后续任务很重要时,校准这些输出就成了必要步骤。
概率校准是将分类器的原始输出分数转换为更能反映结果真实可能性的概率的过程。一个完美校准的二元分类器具有这样的性质:在其预测概率为p的实例中,实际正例的比例确实接近p。
可视化校准的一种常见方法是使用可靠性图(也称为校准曲线)。此图将预测概率分箱(例如,0-0.1, 0.1-0.2, ..., 0.9-1.0),并针对每个箱,绘制平均预测概率与该箱内正例的实际比例。
对角虚线代表完美的校准。对角线以下的条形表示预测过高(预测概率高于实际频率),而对角线以上的条形表示预测过低。红色条形显示的是未校准的模型,而蓝色条形显示的是应用某种技术后改进的校准效果。
提升算法虽然强大,但可能产生未校准的概率。其累加性质、对误差修正的侧重(常导致对高置信度分类点产生极端分数)以及树构建的具体方式都可能导致这种情况。因此,检查并可能修正XGBoost、LightGBM或CatBoost分类器的校准通常是良好的做法。
两种广泛使用的概率校准方法是Platt缩放和保序回归。这两种方法通常在主分类器训练之后应用,使用一个独立的校准数据集(例如,一个保留验证集),该数据集未用于训练原始模型。使用训练数据进行校准会导致过于乐观的结果。
Platt缩放假定模型输出分数与真实概率之间的偏差可以通过拟合一个S形函数来修正。对于输出分数为s的二元分类器,Platt缩放会找到参数A和B,使得校准后的概率P(class=1∣s)按以下方式估计:
PPlatt(y=1∣s)=1+exp(As+B)1参数A和B通常通过在校准集上优化对数损失(或交叉熵)来获得,将原始模型的得分s与该集中的真实标签y关联起来。
当校准曲线单调递增并呈S形时,Platt缩放效果最佳。相较于保序回归,它计算效率高,且所需数据量相对较少。
保序回归是一种非参数方法。它将一个非递减、分段常数的函数拟合到模型预测分数与校准集中观测目标值之间的关系。它找到最适合(最小二乘意义上)的阶梯函数,该函数保留了输入的顺序。
使用的主要算法是相邻违规池算法(PAVA)。与Platt缩放相比,保序回归对偏差的形状作出的假设较少。如果校准曲线不是S形的,保序回归通常能提供更好的拟合。然而,它通常需要更多数据才能产生稳定的结果,并且有时会在校准概率中产生尖锐的阶跃,这可能并不总是理想的。
Scikit-learn提供了一个方便的封装器CalibratedClassifierCV,用于处理模型训练和校准。它可以使用Platt缩放(method='sigmoid')或保序回归(method='isotonic')进行校准。
CalibratedClassifierCV内部使用交叉验证。对于每个折叠:
最后,基础分类器在所有数据上重新训练,并在交叉验证期间学习到的校准器被平均(或选择)以形成最终校准器。
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.calibration import CalibratedClassifierCV, CalibrationDisplay
from xgboost import XGBClassifier
import matplotlib.pyplot as plt
# 生成合成数据
X, y = make_classification(n_samples=1000, n_features=20, n_informative=10, n_redundant=5, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_train, X_calib, y_train, y_calib = train_test_split(X_train, y_train, test_size=0.3, random_state=42) # 如果不使用交叉验证,则进一步拆分以获得显式校准集
# 1. 训练基础XGBoost模型(示例)
base_model = XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=42)
base_model.fit(X_train, y_train)
y_pred_proba_uncalibrated = base_model.predict_proba(X_test)[:, 1]
# 2. 使用CalibratedClassifierCV进行校准(内部处理交叉验证)
# Platt缩放
calibrated_sigmoid = CalibratedClassifierCV(
base_estimator=base_model,
method='sigmoid',
cv=3 # 使用3折交叉验证
)
calibrated_sigmoid.fit(X_train, y_train) # 在原始训练集上拟合
y_pred_proba_sigmoid = calibrated_sigmoid.predict_proba(X_test)[:, 1]
# 保序回归
calibrated_isotonic = CalibratedClassifierCV(
base_estimator=base_model,
method='isotonic',
cv=3 # 使用3折交叉验证
)
calibrated_isotonic.fit(X_train, y_train)
y_pred_proba_isotonic = calibrated_isotonic.predict_proba(X_test)[:, 1]
# 3. 可视化校准
plt.style.use('seaborn-v0_8-whitegrid')
fig, ax = plt.subplots(figsize=(8, 8))
disp1 = CalibrationDisplay.from_predictions(y_test, y_pred_proba_uncalibrated, n_bins=10, name='未校准XGBoost', ax=ax, marker='^', color='#fa5252')
disp2 = CalibrationDisplay.from_predictions(y_test, y_pred_proba_sigmoid, n_bins=10, name='Platt缩放', ax=ax, marker='o', color='#4dabf7')
disp3 = CalibrationDisplay.from_predictions(y_test, y_pred_proba_isotonic, n_bins=10, name='保序回归', ax=ax, marker='s', color='#69db7c')
ax.set_title('校准曲线(可靠性图)')
ax.set_xlabel('平均预测概率')
ax.set_ylabel('正例比例')
ax.legend()
plt.grid(True)
plt.show()
CalibratedClassifierCV通过交叉验证处理这个问题。如果你手动校准,请确保使用专用的保留集。总而言之,概率校准是分类模型(包括梯度提升机)一项重要的后处理技术。当需要可靠的概率估计时,Platt缩放或保序回归等方法(常通过CalibratedClassifierCV等工具应用)可以显著提高模型预测的可信度和实用性。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造