美文网首页
分类器的不确定度估计

分类器的不确定度估计

作者: 编程回忆录 | 来源:发表于2019-10-30 23:07 被阅读0次

在实际应用中,我们感兴趣的不仅是分类器会预测一个测试点属于哪个类别,还包括对这个预测的置信程度。在实践中,不同类型的错误会在现实应用中导致非常不同的结果。想象一个用于测试癌症的医疗应用。假阳性预测可能只会让患者接受额外的测试,但假阴性预测却可能导致重病没有得到治疗。
scikit-learn中有两个函数可用于获取分类器的不确定度估计:decision_function和predict_prob。大多数分类器(但不是全部)都至少有其中一个函数,很多分类器两个都有。我们来构建一个GradientBoostingClassifier分类器(同时拥有decision_function和predict_prob两个方法)。看一下这两个函数对一个模拟的二维数据集的作用:

import sys
print("Python version:{}".format(sys.version))

import pandas as pd
print("pandas version:{}".format(pd.__version__))

import matplotlib
print("matplotlib version:{}".format(matplotlib.__version__))
import matplotlib.pyplot as plt

import numpy as np
print("Numpy version:{}".format(np.__version__))

import scipy as sp
print("Scipy version:{}".format(sp.__version__))

import IPython
print("IPython version:{}".format(IPython.__version__))

import sklearn
print("scikit-learn version:{}".format(sklearn.__version__))

import mglearn
import graphviz

Python version:3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)]
pandas version:0.23.4
matplotlib version:3.0.2
Numpy version:1.15.4
Scipy version:1.1.0
IPython version:7.2.0
scikit-learn version:0.20.1

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split

X,y=make_circles(noise=0.25,factor=0.5,random_state=1)

# 为了便于说明,我们将两个类别重命名为“blue”和“red”
y_named=np.array(["blue","red"])[y]

# 我们可以对任意个数组调用train_test_split
# 所有的数组的划分方式都是一致的
X_train,X_test,y_train_named,y_test_named,y_train,y_test=train_test_split(X,y_named,y,random_state=0)

# 构建梯度提升模型
gbrt=GradientBoostingClassifier(random_state=0)
gbrt.fit(X_train,y_train_named)

GradientBoostingClassifier(criterion='friedman_mse', init=None,
learning_rate=0.1, loss='deviance', max_depth=3,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_iter_no_change=None, presort='auto', random_state=0,
subsample=1.0, tol=0.0001, validation_fraction=0.1,
verbose=0, warm_start=False)

决策函数

对于二分类情况,decision_function返回值的形状是(n_samples),为每个样本都返回一个浮点数:

print("X_test.shape:{}".format(X_test.shape))
print("Decision function shape:{}".format(gbrt.decision_function(X_test).shape))

X_test.shape:(25, 2)
Decision function shape:(25,)
对于类别1来说,这个值表示模型对该数据点属于“正”类的置信程度。正值表示对正类的偏好,负值表示对“反类”(其他类)的偏好:

# 显示decision_function的前几个数
print("Decision function:\n{}".format(gbrt.decision_function(X_test)[:6]))

Decision function:
[ 4.13592629 -1.7016989 -3.95106099 -3.62599351 4.28986668 3.66166106]
我们可以通过仅查看决策函数的正负号来再现预测值:

print("Thresholded decision function:\n{}".format(gbrt.decision_function(X_test)>0))
print("Prediction:\n{}".format(gbrt.predict(X_test)))

Thresholded decision function:
[ True False False False True True False True True True False True
True False True False False False True True True True True False
False]
Prediction:
['red' 'blue' 'blue' 'blue' 'red' 'red' 'blue' 'red' 'red' 'red' 'blue'
'red' 'red' 'blue' 'red' 'blue' 'blue' 'blue' 'red' 'red' 'red' 'red'
'red' 'blue' 'blue']
对于二分类问题,“反”类始终是classes_属性的第一个元素,“正”类是classes_的第二个元素。因此,如果你想要完全再现predict的输出,需要利用classes_属性:

# 将布尔值True/False转换成0和1
greater_zero=(gbrt.decision_function(X_test)>0).astype(int)
# 利用0和1作为classes_的索引
pred=gbrt.classes_[greater_zero]
# pred与gbrt.predict的输出完全相同
print("pred is equal to predictions:\n{}".format(np.all(pred==gbrt.predict(X_test))))

pred is equal to predictions:
True
decision_function可以在任意范围取值,这取决于数据与模型参数:

decision_function=gbrt.decision_function(X_test)
print("Decision function minimum:{:.2f} maximum:{:.2f}".format(np.min(decision_function),np.max(decision_function)))

Decision function minimum:-7.69 maximum:4.29
由于可以任意缩放,因此decision_function的输出往往很难解释。
在下面的例子中,我们利用颜色编码在二维平面中画出所有点的decision_function,还有决策边界|。我们将训练点画成圆,将测试数据画成三角:

fig,axes=plt.subplots(1,2,figsize=(13,5))
mglearn.tools.plot_2d_separator(gbrt,X,ax=axes[0],alpha=.4,fill=True,cm=mglearn.cm2)
scores_image=mglearn.tools.plot_2d_scores(gbrt,X,ax=axes[1],alpha=.4,cm=mglearn.ReBl)

for ax in axes:
    # 画成训练点和测试点
    mglearn.discrete_scatter(X_test[:,0],X_test[:,1],y_test,markers='^',ax=ax)
    mglearn.discrete_scatter(X_train[:,0],X_train[:,1],y_train,markers='o',ax=ax)
    ax.set_xlabel("Feature 0")
    ax.set_ylabel("Feature 1")
cbar=plt.colorbar(scores_image,ax=axes.tolist())
axes[0].legend(["Test class 0","Test class 1","Train class 0","Train class 1"],ncol=4,loc=(.1,1.1))
image.png

既给出预测结果,又给出分类器的置信程度,这样给出的信息量更大。但在上面的图像中,很难分辨出两个类别之间的边界。

预测概率

predict_prob的输出是每个类别的概率,通常比decision_function的输出更容易理解。对于二分类问题,它的形状始终是(n_samples,2):

print("Shape of probabilities:{}".format(gbrt.predict_proba(X_test).shape))

Shape of probabilities:(25, 2)
每行的第一个元素是第一个类别的估计概率,第二个元素是第二个类别的估计概率。由于predict_proba的输出是一个概率,因此总是在0和1之间,两个类别的元素之和始终为1:

# 显示predict_proba的前几个元素
print("Predicted probabilities:\n{}".format(gbrt.predict_proba(X_test[:6])))

Predicted probabilities:
[[0.01573626 0.98426374]
[0.84575649 0.15424351]
[0.98112869 0.01887131]
[0.97406775 0.02593225]
[0.01352142 0.98647858]
[0.02504637 0.97495363]]
由于两个类别的概率之和为1,因此只有一个类别的概率超过50%。这个类别就是模型的预测结果。
如果模型给出的不确定度符合实际情况,那么这个模型被称为校正(calibratd)模型。在校正模型中,如果预测有70%的确定度,那么它在70%的情况下正确。

fig,axes=plt.subplots(1,2,figsize=(13,5))

mglearn.tools.plot_2d_separator(gbrt,X,ax=axes[0],alpha=.4,cm=mglearn.cm2)
scores_image=mglearn.tools.plot_2d_scores(gbrt,X,ax=axes[1],alpha=.5,cm=mglearn.ReBl,function='predict_proba')

for ax in axes:
    # 画出训练点和测试点
    mglearn.discrete_scatter(X_test[:,0],X_test[:,1],y_test,markers='^',ax=ax)
    mglearn.discrete_scatter(X_train[:,0],X_train[:,1],y_train,markers='o',ax=ax)
    ax.set_xlabel("Feature 0")
    ax.set_ylabel("Feature 1")
cbar=plt.colorbar(scores_image,ax=axes.tolist())
axes[0].legend(["Test class 0","Test class 1","Train class 0","Train class 1"],ncol=4,loc=(.1,1.1))
image.png

上图中的边界更加 明确,不确定的小块区域清晰可见。

相关文章

  • 分类器的不确定度估计

    在实际应用中,我们感兴趣的不仅是分类器会预测一个测试点属于哪个类别,还包括对这个预测的置信程度。在实践中,不同类型...

  • 机器学习代码实现 决策树(一)

    信息增益 信息熵表示的是不确定度。均匀分布时,不确定度最大,此时熵就最大。当选择某个特征对数据集进行分类时,分类后...

  • scikit-learn 估计器 · 距离方法

    本节和后面几个章节,将记录scikit-learn估计器。 估计器主要用于分类任务,主要有两个函数: fit() ...

  • 开发集和测试集需要多大(译)

    开发集应该足够大,这样尝试不同算法时你就能检测出它们的不同。例如,分类器A的精确度是90.0%,分类器B的精确度是...

  • scikit_learn学习笔记二——scikit learn基

    scikit-learn基础介绍 估计器(Estimator) 可以直接理解成分类器 主要包含两个函数:fit(x...

  • 不确定度

    学习不确定度要带着以下问题去学,认真思考。 1 什么是不确定度? 不确定度的定义,不确定度与误差 2 不确定度的...

  • 数据分析:信用卡违约率分析,利用GridSearchCV进行参数

    分类器: 随机森林分类器(RandomForest):包含多个决策树的分类器,每一个子分类器都是一颗CART分类器...

  • 交叉验证

    交叉验证 (Cross validation) 有时亦称循环估计, 是用来验证分类器的性能的一种统计分析方法。它用...

  • 损失函数

    线性分类器简介 线性评分函数 阐明线性分类器 损失函数多分类SVMsoftmax分类器SVM和softmax的比较...

  • 不确定度

    CNAS-CL07:2011 GB/T27411-2012 JJF1059.1-2012 JJF1059.2-20...

网友评论

      本文标题:分类器的不确定度估计

      本文链接:https://www.haomeiwen.com/subject/ijzavctx.html