1.16. 概率校准#
在执行分类时,您通常不仅希望预测类别标签,还希望获得相应标签的概率。这个概率为您提供了一定程度的预测信心。一些模型可能提供较差的类别概率估计,有些甚至不支持概率预测(例如,SGDClassifier 的某些实例)。校准模块允许您更好地校准给定模型的概率,或者添加对概率预测的支持。
良好校准的分类器是概率分类器,其 predict_proba 方法的输出可以直接解释为置信度水平。例如,一个良好校准的(二元)分类器应该对样本进行分类,使得在它给出接近 0.8 的 predict_proba 值的样本中,大约 80% 实际属于正类。
在展示如何重新校准分类器之前,我们首先需要一种方法来检测分类器的校准程度。
注意
针对概率预测的严格适当评分规则,例如 sklearn.metrics.brier_score_loss 和 sklearn.metrics.log_loss,同时评估模型的校准(可靠性)和区分能力(分辨率),以及数据的随机性(不确定性)。这源于 Murphy 著名的布里尔分数分解 [1]。由于不清楚哪个项占主导地位,该分数对于单独评估校准的用途有限(除非计算分解的每一项)。例如,较低的布里尔损失并不一定意味着更好的校准模型,它也可能意味着校准更差但具有更多区分能力的模型,例如使用了更多的特征。
1.16.1. 校准曲线#
校准曲线,也称为可靠性图(Wilks 1995 [2]),比较二元分类器的概率预测校准得如何。它以 y 轴上的正标签频率(更准确地说,是条件事件概率 \(P(Y=1|\text{predict_proba})\) 的估计)来绘制,x 轴上是模型的预测概率 predict_proba。棘手的部分是如何获得 y 轴的值。在 scikit-learn 中,这是通过对预测进行分箱来实现的,使得 x 轴代表每个箱中的平均预测概率。y 轴是给定该箱预测的正例比例,即属于正类的样本比例(在每个箱中)。
顶部的校准曲线图是使用 CalibrationDisplay.from_estimator 创建的,它使用 calibration_curve 来计算每个箱的平均预测概率和正例比例。 CalibrationDisplay.from_estimator 接受一个已拟合的分类器作为输入,用于计算预测概率。因此,分类器必须具有 predict_proba 方法。对于少数没有 predict_proba 方法的分类器,可以使用 CalibratedClassifierCV 来校准分类器输出的概率。
底部的直方图通过显示每个预测概率箱中的样本数量,对每个分类器的行为提供了一些见解。
LogisticRegression 本身更有可能返回良好校准的预测,因为它具有针对其损失的规范链接函数,即 对数损失 的 logit 链接。在无惩罚的情况下,这会导致所谓的平衡属性,参见 [8] 和 逻辑回归。在上图中,数据是根据线性机制生成的,这与 LogisticRegression 模型一致(模型是“良好指定的”),并且正则化参数 C 的值经过调整是合适的(既不太强也不太弱)。因此,该模型从其 predict_proba 方法返回准确的预测。与此相反,其他所示模型返回有偏差的概率;每个模型的偏差不同。
GaussianNB(朴素贝叶斯)倾向于将概率推向 0 或 1(注意直方图中的计数)。这主要是因为它假设给定类别时特征是条件独立的,而在这个包含 2 个冗余特征的数据集中并非如此。
RandomForestClassifier 显示出相反的行为:直方图显示在概率大约 0.2 和 0.9 处有峰值,而接近 0 或 1 的概率非常罕见。Niculescu-Mizil 和 Caruana [3] 对此进行了解释:“像 bagging 和随机森林这样对基本模型集进行平均预测的方法,在预测接近 0 和 1 时可能会遇到困难,因为底层基本模型的方差会使接近 0 或 1 的预测偏离这些值。由于预测被限制在区间 [0,1],由方差引起的误差在 0 和 1 附近往往是单侧的。例如,如果一个模型应该预测 \(p = 0\),bagging 实现这一目标的唯一方法是所有 bagged 树都预测为零。如果我们向 bagging 平均的树中添加噪声,这种噪声会导致一些树对这种情况预测大于 0 的值,从而使 bagged 集成的平均预测偏离 0。我们在随机森林中观察到这种效应最强烈,因为使用随机森林训练的基本层树由于特征子集化而具有相对较高的方差。”因此,校准曲线显示出特征性的 S 形,表明分类器通常可以更信任其“直觉”并返回更接近 0 或 1 的概率。
LinearSVC (SVC) 显示出比随机森林更明显的 S 形曲线,这是最大边距方法的典型特征(比较 Niculescu-Mizil 和 Caruana [3]),这些方法侧重于难以分类的样本,即靠近决策边界的样本(支持向量)。
1.16.2. 校准分类器#
校准分类器包括拟合一个回归器(称为校准器),它将分类器的输出(由 decision_function 或 predict_proba 给出)映射到 [0, 1] 中的校准概率。用 \(f_i\) 表示给定样本的分类器输出,校准器试图预测条件事件概率 \(P(y_i = 1 | f_i)\)。
理想情况下,校准器是在独立于用于拟合分类器本身的训练数据的数据集上拟合的。这是因为分类器在其训练数据上的性能会优于新数据。使用训练数据的分类器输出来拟合校准器会导致校准器有偏差,它将概率映射到比应有的值更接近 0 和 1 的位置。
1.16.3. 用法#
CalibratedClassifierCV 类用于校准分类器。
CalibratedClassifierCV 使用交叉验证方法来确保始终使用无偏数据来拟合校准器。数据被分成 \(k\) 个 (train_set, test_set) 对(由 cv 确定)。当 ensemble=True(默认值)时,以下过程会针对每个交叉验证拆分独立重复:
在训练子集上训练
base_estimator的克隆训练好的
base_estimator在测试子集上进行预测使用预测来拟合校准器(sigmoid 或保序回归器)(当数据是多类别时,为每个类别拟合一个校准器)
这会产生一个由 \(k\) 个 (classifier, calibrator) 对组成的集成,其中每个校准器将其对应分类器的输出映射到 [0, 1]。每个对都暴露在 calibrated_classifiers_ 属性中,其中每个条目都是一个带有 predict_proba 方法的校准分类器,该方法输出校准后的概率。CalibratedClassifierCV 主实例的 predict_proba 输出对应于 calibrated_classifiers_ 列表中的 \(k\) 个估计器的预测概率的平均值。predict 的输出是具有最高概率的类别。
当使用 ensemble=True 时,仔细选择 cv 非常重要。在每次拆分中,所有类别都应同时存在于训练子集和测试子集中。当某个类别在训练子集中缺失时,对于该拆分的 (classifier, calibrator) 对,该类别的预测概率将默认为 0。这会使 predict_proba 产生偏差,因为它对所有对进行了平均。当某个类别在测试子集中缺失时,该类别的校准器(在该拆分的 (classifier, calibrator) 对中)是在没有正类的数据上拟合的。这会导致校准无效。
当 ensemble=False 时,交叉验证用于通过 cross_val_predict 获取所有数据的“无偏”预测。然后使用这些无偏预测来训练校准器。calibrated_classifiers_ 属性仅包含一个 (classifier, calibrator) 对,其中分类器是在所有数据上训练的 base_estimator。在这种情况下,CalibratedClassifierCV 的 predict_proba 输出是从单个 (classifier, calibrator) 对获得的预测概率。
ensemble=True 的主要优势是受益于传统的集成效应(类似于 Bagging meta-estimator)。由此产生的集成应该既能很好地校准,又比 ensemble=False 更准确一些。ensemble=False 的主要优势在于计算:它通过仅训练单个基本分类器和校准器对来减少总拟合时间,减小最终模型大小并提高预测速度。
或者,可以使用 FrozenEstimator 作为 CalibratedClassifierCV(estimator=FrozenEstimator(estimator)) 来校准一个已经拟合好的分类器。用户有责任确保用于拟合分类器的数据与用于拟合回归器的数据不相交。
CalibratedClassifierCV 通过 method 参数支持使用两种回归技术进行校准:"sigmoid" 和 "isotonic"。
1.16.3.1. Sigmoid#
sigmoid 回归器,method="sigmoid",基于 Platt 的逻辑模型 [4]
其中 \(y_i\) 是样本 \(i\) 的真实标签,\(f_i\) 是未校准分类器对样本 \(i\) 的输出。\(A\) 和 \(B\) 是在通过最大似然法拟合回归器时确定的实数。
sigmoid 方法假设 校准曲线 可以通过对原始预测应用 sigmoid 函数来校正。这一假设已在 Platt 1999 [4] 的第 2.1 节中对各种基准数据集上的常见核函数 支持向量机 进行了经验证明,但在一般情况下不一定成立。此外,如果校准误差是对称的,即每个二元类别的分类器输出都呈正态分布且具有相同的方差 [7],则逻辑模型效果最佳。对于高度不平衡的分类问题,这可能是一个问题,因为输出没有相等的方差。
一般来说,这种方法对于小样本量或当未校准模型信心不足且对高输出和低输出具有相似校准误差时最有效。
1.16.3.2. 保序#
method="isotonic" 拟合一个非参数保序回归器,它输出一个阶梯式非递减函数,参见 sklearn.isotonic。它最小化
条件是 \(\hat{f}_i \geq \hat{f}_j\),只要 \(f_i \geq f_j\)。\(y_i\) 是样本 \(i\) 的真实标签,\(\hat{f}_i\) 是校准分类器对样本 \(i\) 的输出(即校准概率)。与 'sigmoid' 相比,这种方法更具通用性,因为唯一的限制是映射函数单调递增。因此,它功能更强大,可以校正未校准模型的任何单调失真。然而,它更容易过拟合,尤其是在小数据集上 [6]。
总的来说,当有足够的数据(大于约 1000 个样本)以避免过拟合时,'isotonic' 的性能将与 'sigmoid' 相当或更好 [3]。
注意
对 AUC 等排名指标的影响
通常期望校准不会影响 ROC-AUC 等排名指标。然而,当使用 method="isotonic" 时,这些指标在校准后可能会有所不同,因为保序回归会在预测概率中引入平局。这可以被视为模型预测不确定性的一部分。如果您严格希望保持排名和 AUC 分数,请使用 method="sigmoid",它是一个严格单调的变换,因此可以保持排名。
1.16.3.3. 多类别支持#
保序和 sigmoid 回归器都只支持一维数据(例如,二元分类输出),但如果 base_estimator 支持多类别预测,则会扩展为多类别分类。对于多类别预测,CalibratedClassifierCV 以 OneVsRestClassifier 方式对每个类别分别进行校准 [5]。在预测概率时,会分别预测每个类别的校准概率。由于这些概率不一定总和为一,因此会进行后处理以将其归一化。
另一方面,温度缩放通过使用 logits 并最终应用 softmax 函数自然地支持多类别预测。
1.16.3.4. 温度缩放#
对于具有 \(n\) 个类别的多类别分类问题,温度缩放 [9],method="temperature",通过使用温度参数 \(T\) 修改 softmax 函数来生成类别概率
其中,对于给定样本,\(z\) 是由要校准的估计器预测的每个类别的 logits 向量。在 scikit-learn 的 API 中,这对应于 decision_function 的输出或 predict_proba 的对数。通过首先添加一个微小的正常量以避免零的对数引起的数值问题,然后应用自然对数,将概率转换为 logits。
参数 \(T\) 是通过在保留(校准)集上最小化 log_loss(即交叉熵损失)来学习的。请注意,\(T\) 不会影响 softmax 输出中最大值的位置。因此,温度缩放不会改变校准估计器的准确性。
温度缩放相对于其他校准方法的主要优势在于,它提供了一种自然的方式来获得(更好)校准的多类别概率,只需一个自由参数,而不是使用为每个单独类别添加更多参数的“一对多”方案。
示例
References