Scikit Learn 中分类器的概率校准

297 阅读3分钟

机器学习中的分类器经常提供概率来表明它们对预测的信心程度。然而,概率可能没有经过很好的校准。这意味着它们不能准确地代表预测类别的真实可能性。为了获得校准良好的概率,通过概率校准来映射输出概率。Scikit-learn 库包含通过概率校准提高分类器准确性的技术。

确定分类模型的估计概率与所预测事件的实际概率对应的准确程度的过程称为概率校准。

Scikit-learn 中有两种常见的概率校准方法:

  1. Platt Scaling(逻辑回归)方法: 通过此方法完成将逻辑回归模型拟合到分类器的输出概率。通过使用最大似然估计,根据原始概率建立校准的概率映射函数。在逻辑回归的帮助下,Scikit-learn 的 CaliberatedClassifierCV 类有助于 ****概率校准。
  2. 等张回归: 在此方法中,真实概率被认为与原始概率单调相关(数学概念,其中函数或序列持续增加或持续减少)。分类器的输出概率适合非参数等渗回归模型。该模型学习单调递增的函数,将原始概率映射到校准概率。Scikit 了解到等渗回归类对于实现等渗校准非常有用。

使用 pip 安装 scikit-learn 的命令是:

pip install scikit-learn

示例 1: 在此代码中,我们将使用 scikit-learn 中的 Platt Scaling 来演示二元分类问题的概率校准。

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.calibration import CalibratedClassifierCV
import numpy as np

# 加载Iris数据集
iris = load_iris()
X = iris.data
y = iris.target

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练逻辑回归分类器
clf = LogisticRegression()
clf.fit(X_train, y_train)

# 使用Platt Scaling创建校准分类器
calibrated_clf = CalibratedClassifierCV(clf, method='sigmoid')
calibrated_clf.fit(X_train, y_train)

# 对测试集进行预测
y_proba = calibrated_clf.predict_proba(X_test)

# 打印预测的类别标签和概率
print("预测概率:\n",[np.argmax(prob) for prob in y_proba])

输出:

预测概率:
 [2, 0, 2, 1, 2, 0, 1, 2, 2, 1, 2, 0, 0, 0, 0, 2, 2, 1, 1, 2, 0, 2, 0, 2, 2, 2, 2, 2, 0, 0]

说明: 上述代码中使用的函数有:

  • load_iris():加载 Iris 数据集
  • train_test_split():将数据集拆分为训练集和测试集
  • LogisticRegression():作为基分类器
  • CaliberatedClassifierCV():用于概率校准

首先加载 iris 数据集,并将特征和目标变量分别分配给 X 和 Y。接下来,使用train_test_split函数将数据集分为训练集和测试集。这里,80%的数据用于训练(X_train,y_train),20%用于测试(X_test,y_test)。

现在,已经创建了caliberated_clf,然后使用训练数据来训练校准的分类器。接下来,使用校准的分类器对测试集进行预测。每个类别的预测概率存储在y_proba中。

最后,打印预测的类标签和概率。 

  • 预测标签 (y_pred) 表示测试集中每个样本的类预测
  • 预测概率 (y_proba) 显示每个类别的概率估计

二元分类的概率校准曲线

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.calibration import CalibratedClassifierCV
from sklearn.calibration import CalibrationDisplay
import matplotlib.pyplot as plt

# 加载癌症乳腺数据集
cancer = load_breast_cancer()
X = cancer.data
y = cancer.target

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 分类器
svc = SVC()
tree = DecisionTreeClassifier()
log = LogisticRegression(C=0.5)
gnb = GaussianNB()
svc_sigmoid = CalibratedClassifierCV(svc, cv=3, method="sigmoid", ensemble=True)
tree_isotonic = CalibratedClassifierCV(tree, cv=3, method="isotonic", ensemble=True)
gnb_sigmoid = CalibratedClassifierCV(gnb, cv=3, method="sigmoid", ensemble=True)

classifiers = {
	"Logistic":log,
	"Naive Bayes" : gnb,
	"SVM + sigmoid": svc_sigmoid,
	"Decision Tree + Isotonic": tree_isotonic,
	"Naive Bayes + Sigmoid" : gnb_sigmoid
}

# 绘制每个分类器的概率校准曲线
fig, ax = plt.subplots(figsize=(7, 5), dpi=150)
ax.plot([0, 1], [0, 1], linestyle='--', color='gray')

for name, clf in classifiers.items():
	clf.fit(X_train, y_train)
	clf_disp = CalibrationDisplay.from_estimator(clf, X_test, y_test, n_bins=10, name=name, ax=ax)

plt.title('Probability Calibration Curve')
plt.legend(loc="best")
plt.show()

输出

image.png