1. 不平衡分类中的概率校准问题
在机器学习实践中,我们经常遇到类别分布严重不平衡的数据集。这类数据集中,少数类样本的数量可能只占总样本量的1%甚至更少。传统分类算法在这种场景下往往会偏向多数类,导致对少数类的识别能力不足。
概率预测在不平衡分类问题中尤为重要,因为:
- 精确的概率估计是ROC曲线和PR曲线分析的基础
- 为后续决策阈值调整提供可靠依据
- 使不同模型的性能比较更加准确
然而,许多机器学习模型预测的概率或类概率分数存在校准问题。所谓校准,指的是预测概率应与实际观察到的频率相匹配。例如,当我们预测100个样本的正类概率为0.8时,如果模型校准良好,那么其中应有约80个样本确实属于正类。
2. 概率校准的核心方法
2.1 Platt缩放法
Platt缩放是一种基于逻辑回归的概率校准方法,特别适用于SVM等算法的输出校准。其核心思想是通过sigmoid函数将原始分数映射到概率空间:
P(y=1|x) = 1 / (1 + exp(A*f(x) + B))其中f(x)是模型的原始输出分数,A和B是通过极大似然估计学习得到的参数。
提示:Platt缩放最适合校正呈现S型失真的概率预测,对小数据集表现较好。
2.2 保序回归法
保序回归是一种非参数校准方法,它寻找一个单调递增的函数来转换原始分数。相比Platt缩放,它能校正更复杂的失真模式,但需要更多数据支持:
- 将预测概率排序
- 在保持顺序的前提下最小化平方误差
- 通过线性插值得到最终转换函数
3. 实践中的概率校准技巧
3.1 校准评估策略
在校准过程中,必须严格分离训练集和校准集,避免数据泄露。推荐做法:
- 使用分层k折交叉验证
- 内层循环用于模型训练和校准
- 外层循环用于评估校准效果
from sklearn.calibration import CalibratedClassifierCV from sklearn.model_selection import RepeatedStratifiedKFold # 3折校准,保持类别分布 calibrator = CalibratedClassifierCV( base_estimator=model, method='isotonic', cv=3 ) # 外层10折评估 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3) scores = cross_val_score(calibrator, X, y, cv=cv, scoring='roc_auc')3.2 处理极端不平衡数据
当少数类样本极少时,校准过程需要特别注意:
- 增加校准折数(cv值)可能导致每折中的少数类样本不足
- 可考虑使用分层抽样确保每折都有代表性样本
- 在数据极少时,Platt缩放通常比保序回归更稳定
4. 典型算法校准实践
4.1 支持向量机(SVM)校准
SVM的决策函数值不是概率,默认需要通过Platt缩放转换:
from sklearn.svm import SVC svm = SVC(kernel='rbf', probability=False) # 注意不启用内置概率 calibrated_svm = CalibratedClassifierCV(svm, method='sigmoid') # 带类别权重的版本 weighted_svm = SVC(class_weight='balanced') calibrated_weighted = CalibratedClassifierCV(weighted_svm, method='isotonic')4.2 决策树校准
决策树的概率基于叶节点中的类别分布,常过于自信:
from sklearn.tree import DecisionTreeClassifier tree = DecisionTreeClassifier(min_samples_leaf=10) calibrated_tree = CalibratedClassifierCV(tree, method='sigmoid')4.3 K近邻校准
KNN的概率估计依赖邻居投票,受k值影响大:
from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import GridSearchCV knn = KNeighborsClassifier() param_grid = { 'cv': [2, 3, 4], 'method': ['sigmoid', 'isotonic'] } grid = GridSearchCV( CalibratedClassifierCV(knn), param_grid, scoring='roc_auc' )5. 校准效果评估与比较
5.1 定量评估指标
- Brier分数:衡量概率预测的准确性,越小越好
- 可靠性曲线:可视化预测概率与实际频率的一致性
- ROC AUC:评估排序能力,但依赖校准质量
5.2 典型改进幅度
根据实践经验,校准通常能带来以下提升:
| 算法 | 原始AUC | 校准后AUC | 提升幅度 |
|---|---|---|---|
| SVM | 0.804 | 0.875 | +8.9% |
| 决策树 | 0.842 | 0.859 | +2.0% |
| 加权SVM | 0.875 | 0.966 | +10.4% |
6. 高级技巧与注意事项
校准与类别平衡的协同:先应用类别权重或采样方法,再进行校准,效果通常最佳
校准数据量要求:保序回归至少需要1000个校准样本,Platt缩放可少至100个
模型堆叠中的校准:在集成学习中,应先校准基学习器,再组合预测
在线学习的校准:对于数据流,可采用滑动窗口或衰减因子动态更新校准参数
多类问题的校准:使用一对多策略,为每个类单独建立校准器
常见错误规避:
- 避免在校准过程中泄露测试集信息
- 不要在校准前使用基于概率的指标选择模型
- 警惕校准后概率的过度平滑问题
- 极端不平衡时,优先选择Platt缩放
7. 完整实现示例
以下是一个整合了类别平衡和概率校准的完整流程:
from sklearn.datasets import make_classification from sklearn.ensemble import RandomForestClassifier from sklearn.calibration import CalibrationDisplay from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt # 生成极端不平衡数据 X, y = make_classification(n_samples=10000, n_classes=2, weights=[0.99], flip_y=0) # 分层分割 X_train, X_test, y_train, y_test = train_test_split( X, y, stratify=y, test_size=0.3 ) # 基础模型 model = RandomForestClassifier(n_estimators=100, class_weight='balanced') # 校准流程 calibrated = CalibratedClassifierCV( model, method='isotonic', cv=5 ) calibrated.fit(X_train, y_train) # 可视化校准效果 disp = CalibrationDisplay.from_estimator( calibrated, X_test, y_test, n_bins=10, name='Calibrated RF' ) plt.show()通过系统化的概率校准,我们能够在不平衡分类任务中获得更可靠的预测概率,为后续的模型评估、比较和决策提供坚实基础。实践表明,结合类别平衡技术的校准流程,通常能使模型的业务效用提升20-30%。