深度理解受试者工作特征(ROC)曲线

目录

  • 1、分类结果混淆矩阵
    • 举例:
  • 2、ROC
    • 2.1、ROC曲线是从阈值选取角度出发来研究学习器泛化性能的有力工具
    • 2.2、ROC曲线
    • 2.3、主要作用:
    • 2.4、优点:
    • 举例1:
    • 举例2:
  • 3、AUC
  • 4、Python代码
    • 方法一:
    • 方法二:

我们通常使用ROC和AUC来衡量分类算法在二分类问题上表现的好坏。

1、分类结果混淆矩阵

在二分类问题上,可将样例根据其真实类别和分类模型预测的类别分为如下四种(1表示类别为真,0表示类别为假):

  • 真正例TP(true postive):样本真实类别为1,学习模型预测的类别也为1;
  • 假正例FP(false postive):样本真实类别为0,学习模型预测的类别为1;
  • 真反例TN(true negative):样本真实类别为0,学习模型预测的类别也为0;
  • 假反例FN(false negative):样本真实类别为1,学习模型预测的类别也为0。

深度理解受试者工作特征(ROC)曲线_第1张图片

举例:

假如我们有100个正例,其中85个被预测为正例,15个被预测为反例;
80个反例,其中70个被预测成为反例,10个被预测成为正例。那么:
深度理解受试者工作特征(ROC)曲线_第2张图片

TP 85
FN 15
TN 70
FP 10

结果如下:
深度理解受试者工作特征(ROC)曲线_第3张图片

2、ROC

2.1、ROC曲线是从阈值选取角度出发来研究学习器泛化性能的有力工具

很多学习器是为测试样本产生一个实值或概率预测,然后将这个预测值与一个分类阈值进行比较,若大于阈值则分为正类,否则为反类。例如,神经网络在一般情形下是对每个测试样本预测出一个[0.0,1.0]之间的实值,然后将这个值与阈值(比如0.5)进行比较,大于阈值(比如0.5)则判为正例,否则为反例。这个阈值设置的好坏,直接决定了学习器的泛化能力。

在不同的应用任务中,我们可根据任务需求来采用不同的阈值。例如,若我们更重视“查准率”,则可以把阈值设置的大一些,让分类器的预测结果更有把握;若我们更重视“查全率”,则可以把阈值设置的小一些,让分类器预测出更多的正例。因此,阈值设置的好坏,体现了综合考虑学习器在不同任务下的泛化性能的好坏。

ROC全称是“受试者工作特征”(Receiver OperatingCharacteristic)曲线。我们根据学习器的预测结果,把阈值从0变到最大,即刚开始是把每个样本作为正例进行预测,随着阈值的增大,学习器预测正样例数越来越少,直到最后没有一个样本是正样例。在这一过程中,每次计算出两个重要量的值,分别以它们为横、纵坐标作图,就得到了“ROC曲线”。

2.2、ROC曲线

设计一个指标来判断分类器的好坏,这里我们使用

真正例率TPR假正例率FPR来判断,它们的定义如下:
T P R = T P / ( T P + F N ) F P R = F P / ( F P + T N ) \begin{array}{l} T P R=T P /(T P+F N) \\ F P R=F P /(F P+T N) \end{array} TPR=TP/(TP+FN)FPR=FP/(FP+TN)

上面的例子中:
T P R = T P T P + F N = 85 85 + 15 = 85 100 F P R = F P F P + T N = 10 10 + 70 = 10 80 \begin{array}{l} T P R=\dfrac{TP}{TP+FN}=\dfrac{85}{85+15}=\dfrac{85}{100}\\ F P R=\dfrac{FP}{FP+TN}=\dfrac{10}{10+70}=\dfrac{10}{80} \end{array} TPR=TP+FNTP=85+1585=10085FPR=FP+TNFP=10+7010=8010

TPR越高,FPR越低,则可以证明分类器分类效果越好

但是两者又是相互矛盾的,我们为了降低假正例率FP,让样本被分为正例的要求变得更高,这样反例被误判为正例的个数FP(假正例)就会减少,那么FPR的值就会降低

但与此同时,有一部分不是很像正例的正例会被我们错误的归为反例,FN(假反例)的个数就会升高,TPR的值也会降低。反之,TPR的值增大,FPR的值也会增大。

所以单单凭TPR和FPR的两个值是没有办法比较两个分类器的好坏。这里就提出了ROC曲线。我们使用TPR作为纵轴,FPR作为横轴作图,就可以得到ROC曲线。

对角线对应于“随机猜测”模型,而点(0,1)则对应于将所有正例预测为真正例、所有反例预测为真反例的“理想模型”。
深度理解受试者工作特征(ROC)曲线_第4张图片绘图过程如下:给定 m + m^+ m+个正例, m − m^- m个反例,根据学习器预测结果对样例进行排序,然后把分类器阈值设为最大,此时所有的样例均预测为反例,此时真正例率和假正例率均为 0,在坐标 (0,0) 处标一个点。然后,将分类阈值依次设为每个样例的预测值(预测概率),即依次将每个样例划分为正例。

  • 设前一个标记坐标点为 ( x , y ) (x,y) (x,y),当前若为真正例(真正例率TPR),则对应标记点的坐标为 ( x , y + 1 m + ) (x,y+\dfrac{1}{m^+}) (x,y+m+1)
  • 当前若为假正例(假正例率FPR),则对应标记点的坐标为 ( x + 1 m − , y ) (x+\dfrac{1}{m^-},y) (x+m1,y)。然后用线段连接相邻点即得ROC曲线。

2.3、主要作用:

  1. ROC曲线能很容易的查出任意阈值对学习器的泛化性能影响;
  2. 有助于选择最佳的阈值。ROC曲线越靠近左上角,模型的查全率就越高。最靠近左上角的ROC曲线上的点是分类错误最少的最好阈值,其假正例和假反例总数最少;
  3. 可以对不同的学习器比较性能。将各个学习器的ROC曲线绘制到同一坐标中,直观地鉴别优劣,靠近左上角的ROC曲所代表的学习器准确性最高。

2.4、优点:

  1. 该方法简单、直观、通过图示可观察分析方法的准确性,并可用肉眼作出判断。ROC曲线将真正例率和假正例率以图示方法结合在一起,可准确反映某种学习器真正例率和假正例率的关系,是检测准确性的综合代表;

  2. 在生物信息学上的优点:ROC曲线不固定阈值,允许中间状态的存在,利于使用者结合专业知识,权衡漏诊与误诊的影响,选择一个更加的阈值作为诊断参考值。

举例1:

假如我们已经得到了所有样本的概率输出(属于正样本的概率),现在的问题是如何改变这个阈值(概率输出)?

我们根据每个测试样本属于正样本的概率值从大到小排序。

下图是一个示例,图中共有20个测试样本,“Class”一栏表示每个测试样本真正的标签(p表示正样本,n表示负样本),“Score”表示每个测试样本属于正样本的概率
深度理解受试者工作特征(ROC)曲线_第5张图片

  • 我们从高到低,依次将“Score”值作为阈值,当测试样本属于正样本的概率大于或等于这个阈值时,我们认为它为正样本,否则为负样本。
  • 举例来说,对于图中的第4个样本,其“Score”值为0.6,那么样本1,2,3,4都会被认为是正样本,因为它们的“Score”值都大于等于0.6,而其他样本则都认为是负样本。
  • 每次选取一个不同的阈值,我们就可以得到一组FPR和TPR,即ROC曲线上的一点。
  • 这样一来,我们一共得到了20组FPR和TPR的值,将它们画在ROC曲线的结果如下图:
    深度理解受试者工作特征(ROC)曲线_第6张图片当我们将阈值设置为10时,分别可以得到ROC曲线上的(0,0)(1,1)两个点。将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当阈值取值越多,ROC曲线越平滑。

举例2:

举例帮助理解,使用逻辑回归对数据进行分类,可以得到如下的表格
深度理解受试者工作特征(ROC)曲线_第7张图片这个逻辑回归分类器很好的预测了类别,这个样本有4个正例,3个反例

我们可以按照如下方式绘制ROC曲线图,

  1. 首先设置第一个坐标点在原点(0,0),此时我们的真正例率和假正例率均为0,因此此时正例数为0;
  2. 然后从大到小依次取概率值,取概率为0.9的时候,我们假设概率大于等于0.9的样本点均为正例。如果此时这个样例的真实类别也为正例(即真是类别为1),那么此时我们的坐标点移动到 ( 0 , 0 + 1 4 ) (0,0+\dfrac{1}{4}) (0,0+41),否则样本点移动到 ( 0 + 1 3 , 0 ) (0+\dfrac{1}{3},0) (0+31,0)
  3. 接下来我们取概率值为0.7的时候,此时我们假设概率大于等于0.7的样本点均为正例,那么此时我们没有必要考虑概率值为0.9的样本点。
    因为当我们设置模型判断一个样本为正例的阈值概率0.9的时候,此时如果我们把一个反例错判为正例,那么在阈值概率为0.7的时候,依旧会把这个反例错认为是正例,如果在阈值概率为0.9的时候,我们判断一个正例为正例,那么在阈值为0.7的时候我们依旧会做出同样的判断。
    因为取概率值为0.7的时,样本点真实类别也是正例,所以此时样本点坐标为 ( 0 , 1 4 + 1 4 ) (0, \dfrac{1}{4}+\dfrac{1}{4}) (0,41+41)。也就是说我们用0.7作为阈值概率时,真正例率TPR=0.5假正例率FPR=0
  4. 重复上述步骤,就可以得到一条ROC曲线。通过ROC曲线我们就可以判断两个分类器的好坏,如下图:
    深度理解受试者工作特征(ROC)曲线_第8张图片

如上图,我们就可以说分类器1的分类效果好于分类器2。

因为在相同的FPR的条件下,分类器1的TPR要高于分类器2的TPR。

3、AUC

但是如果出现了下面的情况:
深度理解受试者工作特征(ROC)曲线_第9张图片我们此时没有办法直观的说明两个分类器那个更好一些,

这种情况我们一般使用AUC的值来进行判断。

AUC(Area Under ROC Curve)也就是直ROC曲线下面的面积

通常我们认为AUC值大的分类器性能较好

4、Python代码

方法一:

def anotherPlotROC(predStrengths, classLabels): #0--->1
    import matplotlib.pyplot as plt
    cur = (0.0, 0.0)
    ySum = 0.0
    numPosClas = sum(np.array(classLabels) == 1.0)
    yStep = 1/float(numPosClas); xStep = 1/float(len(classLabels) - numPosClas)
    sortedIndicies = predStrengths.argsort()
    fig = plt.figure()
    fig.clf()
    ax = plt.subplot(111)

    for index in sortedIndicies.tolist()[0][::-1]:
        if classLabels[index] == 1.0:   #TP真正例
            delX = 0; delY = yStep
        else:
            delX = xStep; delY = 0  #FP假正例
            ySum += cur[1]

        ax.plot([cur[0], cur[0] + delX], [cur[1], cur[1]+delY], c='b')
        cur = (cur[0]+delX, cur[1]+delY)

    ax.plot([0,1], [0,1], 'b--')
    plt.xlabel("False positive rate"); plt.ylabel("True positive rate")
    plt.title('ROC')
    ax.axis([0,1,0,1])
    print("the Area Under the Curve is", ySum*xStep)
    plt.show()

使用《机器学习实战》中第五章的病马预测数据使用第八章adaboost分类算法进行分类可得到的ROC曲线如下 :
深度理解受试者工作特征(ROC)曲线_第10张图片

方法二:

接下来就是利用python实现ROC曲线,sklearn.metricsroc_curve, auc两个函数

fpr, tpr, thresholds  =  roc_curve(y_test, scores) 

其中y_test为测试集的结果,scores为模型预测的测试集得分(注意:通过decision_function(x_test)计算scores的值);fpr,tpr,thresholds 分别为假正率、真正率和阈值。(应该是不同阈值下的真正率和假正率)。

roc_auc =auc(fpr, tpr) 

其中roc_auc为计算的acu的值。

解释
sklearn.metrics.roc_curve函数提供了很好的解决方案。

首先看一下这个函数的用法:

fpr, tpr, thresholds=sklearn.metrics.roc_curve(y_true,y_score,pos_label=None,sample_weight=None,drop_intermediate=True)

参数解析(来源sklearn官网):

y_true: array, shape = [n_samples]
#True binary labels in range {0, 1} or {-1, 1}. If labels are not binary, pos_label should be explicitly given.

真实标签矩阵

y_score : array, shape = [n_samples]
#
Target scores, can either be probability estimates of the positive class, confidence values, or non-thresholded measure of decisions (as returned by “decision_function” on some classifiers).

模型的预测结果矩阵

pos_label : int or str, default=None
#Label considered as positive and others are considered negative.

标签中认定为正的label个数。

例如:

  • label= [1,2,3,4],如果设置pos_label = 2,则认为3,4为positive,其他均为negtive
sample_weight: array-like of shape = [n_samples]
#optional Sample weights.

采样权重,可选择取其中的一部分进行计算。

drop_intermediate: boolean, optional (default=True)
#Whether to drop some suboptimal thresholds which would not appear on a plotted ROC curve. This is useful in order to create lighter ROC curves.

即可选择去掉一些对于ROC性能不利的阈值,使得得到的曲线有更好的表现性能。

返回值Returns:

thresholds: array, shape = [n_thresholds]
Decreasing thresholds on the decision function used to compute fpr and tpr. thresholds[0] represents no instances being predicted and is arbitrarily set to max(y_score) + 1.

所选择不同的阈值,按照降序排列

fpr : array, shape = [>2]
#Increasing false positive rates such that element i is the false positive rate of predictions with score >= thresholds[i].

根据不同阈值求出的fpr。

tpr: array, shape = [>2]
#Increasing true positive rates such that element i is the true positive rate of predictions with score >= thresholds[i].

根据不同阈值求出来的tpr上述方法可得到一组tpr和fpr,在此基础上即可作出roc曲线。求AUC可通过函数auc(fpr,tpr),其返回值即为AUC的值。

实例分析如下:

import numpy as np
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.metrics import auc
y = np.array([1,1,2,3]) #y为数据的真实标签
scores = np.array([0.1, 0.2, 0.35, 0.8]) #scores为分类其预测的得分
fpr, tpr, thresholds = metrics.roc_curve(y, scores, pos_label=2) #得到fpr,tpr, thresholds

返回值对应如下:
深度理解受试者工作特征(ROC)曲线_第11张图片
得到一组fpr和tpr之后即可画出该次测试对应的roc曲线

plt.plot(fpr,tpr,marker = 'o')
plt.show()

得到ROC曲线:
深度理解受试者工作特征(ROC)曲线_第12张图片求出AUC:

from sklearn.metrics import auc
AUC = auc(fpr, tpr)

最终得到AUC=0.67

参考:1、https://zhuanlan.zhihu.com/p/46438528;
2、https://blog.csdn.net/ice110956/article/details/20288239?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control
3、https://blog.csdn.net/Mr_HHH/article/details/79667677?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control
4、https://blog.csdn.net/xyz1584172808/article/details/81839230
5、https://www.jianshu.com/p/1da84ac7ff03

你可能感兴趣的:(1024,Python精华,Python数学算法,python,机器学习,算法,概率论)