注意:单击此处/muQBjy下载完整的示例代码,或通过Binder在浏览器中运行此示例
在进行分类时,人们经常不仅要预测分类标签,还要预测相关的概率。预测概率可以让人们对预测分类标签具有信心。本示例演示了如何显示预测概率的校准程度以及如何校准未校准的分类器。
该实验是在具有100,000个样本(其中1,000个用于模型训练)和20个特征的二分类的人工数据集上进行的。在这20个特征中,只有2个具有信息性,而10个是冗余的。第一张图显示了逻辑回归,高斯朴素贝叶斯和有等渗校准(isotonic calibration)和sigmoid校准(sigmoid calibration)高斯朴素贝叶斯获得的预测概率。校准性能通过图例中记录的Brier得分进行评估(越小越好)。在这里可以观察到逻辑回归得到了很好的校准,而原始的高斯朴素贝叶斯则表现很差。这是因为多余的特征违反了特征独立性的假设,并导致分类器过分自信,这就是典型的转置sigmoid型曲线。
带有等渗回归(isotonic regression)的高斯朴素贝叶斯概率的校准可以解决此问题,如可以从近对角线的校准曲线中看出。sigmoid校准还可以稍微改善brier得分,尽管不如非参数等渗回归那么强。这可以归因于以下事实:我们拥有大量的校准数据,因此利用非参数模型具有更大灵活性。
第二张图显示了线性支持向量分类器(LinearSVC)的校准曲线。线性支持向量分类器(LinearSVC)表现出与高斯朴素贝叶斯相反的行为:校准曲线是具有sigmoid形的曲线,这对于置信度低的分类器来说是典型的曲线。在线性支持向量分类器(LinearSVC)的情况下,这是由合页损失(hinge loss)的margin属性引起的,该属性使合页损失(hinge loss)可以集中关注于那些靠近决策边界(支持向量)的硬样本(hard samples)。
两种校准均可解决此问题,并产生几乎相同的结果。这表明sigmoid校准可以处理基本分类器的校准曲线是sigmoid的情况(例如,线性支持向量分类器(LinearSVC)),但不可以处理转置sigmoid形(例如,高斯朴素贝叶斯)的情况。
输出:Logistic:Brier: 0.099Precision: 0.872Recall: 0.851F1: 0.862Naive Bayes:Brier: 0.118Precision: 0.857Recall: 0.876F1: 0.867Naive Bayes + Isotonic:Brier: 0.098Precision: 0.883Recall: 0.836F1: 0.859Naive Bayes + Sigmoid:Brier: 0.109Precision: 0.861Recall: 0.871F1: 0.866Logistic:Brier: 0.099Precision: 0.872Recall: 0.851F1: 0.862SVC:Brier: 0.163Precision: 0.872Recall: 0.852F1: 0.862SVC + Isotonic:Brier: 0.100Precision: 0.853Recall: 0.878F1: 0.865SVC + Sigmoid:Brier: 0.099Precision: 0.874Recall: 0.849F1: 0.861print(__doc__)# 作者: Alexandre Gramfort # Jan Hendrik Metzen # 许可证: BSD as pltfrom sklearn import datasetsfrom sklearn.naive_bayes import GaussianNBfrom import LinearSVCfrom sklearn.linear_model import LogisticRegressionfrom import (brier_score_loss, precision_score, recall_score,f1_score)from import CalibratedClassifierCV, calibration_curvefrom sklearn.model_selection import train_test_split# 创建分类任务的数据集,其中有很多冗余的特征而有很少# 具有信息性的特征X, y = datasets.make_classification(n_samples=100000, n_features=20,n_informative=2, n_redundant=10,random_state=42)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.99,random_state=42)def plot_calibration_curve(est, name, fig_index):"""Plot calibration curve for est w/o and with calibration. """# 等渗校准isotonic = CalibratedClassifierCV(est, cv=2, method="isotonic")# sigmoid校准sigmoid = CalibratedClassifierCV(est, cv=2, method="sigmoid")# 做为基准的没有校准的逻辑回归lr = LogisticRegression(C=1.)fig = (fig_index, figsize=(10, 10))ax1 = plt.subplot2grid((3, 1), (0, 0), rowspan=2)ax2 = plt.subplot2grid((3, 1), (2, 0))([0, 1], [0, 1], "k:", label="Perfectly calibrated")for clf, name in [(lr, "Logistic"),(est, name),(isotonic, name + " + Isotonic"),(sigmoid, name + " + Sigmoid")]:(X_train, y_train)y_pred = (X_test)if hasattr(clf, "predict_proba"):prob_pos = clf.predict_proba(X_test)[:, 1]else: # 使用决策函数prob_pos = clf.decision_function(X_test)prob_pos = \(prob_pos - prob_pos.min()) / (prob_pos.max() - prob_pos.min())clf_score = brier_score_loss(y_test, prob_pos, pos_label=())print("%s:" % name)print("\tBrier: %1.3f" % (clf_score))print("\tPrecision: %1.3f" % precision_score(y_test, y_pred))print("\tRecall: %1.3f" % recall_score(y_test, y_pred))print("\tF1: %1.3f\n" % f1_score(y_test, y_pred))fraction_of_positives, mean_predicted_value = \calibration_curve(y_test, prob_pos, n_bins=10)(mean_predicted_value, fraction_of_positives, "s-",label="%s (%1.3f)" % (name, clf_score))(prob_pos, range=(0, 1), bins=10, label=name,histtype="step", lw=2)ax1.set_ylabel("Fraction of positives")ax1.set_ylim([-0.05, 1.05])(loc="lower right")ax1.set_title("Calibration plots (reliability curve)")ax2.set_xlabel("Mean predicted value")ax2.set_ylabel("Count")(loc="upper center", ncol=2)plt.tight_layout()# 绘制高斯朴素贝叶斯的校准曲线plot_calibration_curve(GaussianNB(), "Naive Bayes", 1)# 绘制线性支持向量分类器(Linear SVC)的校准曲线plot_calibration_curve(LinearSVC(max_iter=10000), "SVC", 2)()
脚本的总运行时间:(0分钟2.474秒)
估计的内存使用量: 28 MB
下载Python源代码: plot_calibration_curve.py下载Jupyter notebook源代码: plot_calibration_curve.ipynb由Sphinx-Gallery生成的画廊
欢迎大家和我一起沿着scikit-learn文档这条路线,一起巩固机器学习算法基础。(添加微信:mthler,备注:sklearn学习,一起进【sklearn机器学习进步群】开启打怪升级的学习之旅。)