ROC曲线和AUC计算

1. ROC曲线

  • TP(True Positive):指正确分类的正样本数,即预测为正样本,实际也是正样本。
  • FP(False Positive):指被错误的标记为正样本的负样本数,即实际为负样本而被预测为正样本,所以是False。
  • TN(True Negative):指正确分类的负样本数,即预测为负样本,实际也是负样本。
  • FN(False Negative):指被错误的标记为负样本的正样本数,即实际为正样本而被预测为负样本,所以是False。
  • TP+FP+TN+FN:样本总数。
  • TP+FN:实际正样本数。
  • TP+FP:预测结果为正样本的总数,包括预测正确的和错误的。
  • FP+TN:实际负样本数。
  • TN+FN:预测结果为负样本的总数,包括预测正确的和错误的。

FPR指实际负样本中被错误预测为正样本的概率。
真正例率 (TPR) 是召回率的同义词,因此定义如下:

TPR指实际正样本中被预测正确的概率。假正例率 (FPR) 的定义如下:

ROC(receiver operating characteristic),平面的横坐标是false positive rate(FPR)假阳率,纵坐标是true positive rate(TPR)真阳率。

2. ROC计算过程如下:

  • 首先每个样本都需要有一个label值,并且还需要一个预测的score值(取值0到1);
  • 然后按这个score对样本由大到小进行排序,假设这些数据位于表格中的一列,从上到下依次降序;
  • 现在从上到下按照样本点的取值进行划分,位于分界点上面的我们把它归为预测为正样本,位于分界点下面的归为负样本;
  • 分别计算出此时的TPR(Recall)=TP/P和FPR(1-SP)=FP/N,然后在图中绘制(FPR, TPR)点。
  • 从上往下逐个样本计算,最后会得到一条光滑的曲线 。

参考:
Understanding ROC curve

3. AUC计算

ROC曲线围住的面积,越大,分类器效果越好。
AUC(area under the curve)就是ROC曲线下方的面积,取值在0.5到1之间,因为随机猜测得到额AUC就是0.5。面积如下图所示,阴影部分即为AUC面积:

横轴FPR:1-TNR,1-Specificity,FPR越大,预测正类中实际负类越多。

纵轴TPR:Sensitivity(正类覆盖率),TPR越大,预测正类中实际正类越多。

理想目标:TPR=1,FPR=0,即图中(0,1)点,故ROC曲线越靠拢(0,1)点,越偏离45度对角线越好,Sensitivity、Specificity越大效果越好。ROC是光滑的,那么基本可以判断没有太大的overfitting

3.1. 计算代码

import numpy as np
import matplotlib.pyplot as plt

def plotROC(predScore, labels):
    point = (1.0, 1.0) #由于下面排序的索引是从小到大,所以这里从(1,1)开始绘制
    ySum = 0.0 
    numPos = np.sum(np.array(labels)==1.0)
    numNeg = len(labels)-numPos
    yStep = 1/np.float(numPos)
    xStep = 1/np.float(numNeg)
    sortedIndex = predScore.argsort() #对predScore进行排序,的到排序索引值
    fig = plt.figure()
    fig.clf()
    ax = plt.subplot(111)
    for index in sortedIndex.tolist()[0]:
        if labels[index] == 1.0: #如果正样本各入加1,则x不走动,y往下走动一步
            delX = 0
            delY = yStep;
        else:                   #否则,x往左走动一步,y不走动
            delX = xStep
            delY = 0
            ySum += point[1]     #统计y走动的所有步数的和
        ax.plot([point[0], point[0] - delX], [point[1], point[1] - delY],c='b')
        point = (point[0] - delX, point[1] - delY)
    ax.plot([0,1],[0,1],'b--')
    plt.xlabel('False positive rate'); plt.ylabel('True positive rate')
    plt.title('ROC Curve')
    ax.axis([0, 1, 0, 1])
    plt.show() 
    #最后,所有将所有矩形的高度进行累加,最后乘以xStep得到的总面积,即为AUC值
    print "the Area Under the Curve is: ", ySum * xStep

对于ROC曲线绘制中的参数,输入的第二个参数是类别标签(如,+1,-1形成的文件,每行表示一个样本的真实类别);第一个参数则是由模型训练出来的预测强度,如Adaboost对样本i预测的结果为0.67,对i+1个样本预测的结果是0.3,等等,每行一个,格式和classLabels一样。最后绘制ROC曲线的同时,也在输出ROC曲线下方的AUC面积。

4. 选择最佳阈值

要选择最佳阈值,可以将roc曲线的每个点视为单独的分类器。这个小分类器使用得分作为+和 - 之间的边界(即,它被分类为+当前一个以上的所有点)取决于我们的数据集中的 pos/neg分数 - 在50%/ 50%的情况下平行于基线 - 您可以构建iso准确度线并以最佳准确度进行分析。
这里有一张照片可以说明这一点

参考:
ROC Analysis - ML Wiki
Understanding ROC curve

5. ROC与P-R对比

绘制ROC曲线和PR曲线都是选定不同阈值,从而得到不同的x轴和y轴的值,画出曲线。

ROC和PR曲线都被用于评估机器学习算法对一个给定数据集的分类性能,每个数据集都包含固定数目的正样本和负样本。

在ROC空间,ROC曲线越凸向左上方向效果越好。与ROC曲线左上凸不同的是,PR曲线是右上凸效果越好。

定理1:对于一个给定的包含正负样本的数据集,ROC空间和PR空间存在一一对应的关系,也就是说,如果recall不等于0,二者包含完全一致的混淆矩阵。我们可以将ROC曲线转化为PR曲线,反之亦然。

定理2:对于一个给定数目的正负样本数据集,一条曲线在ROC空间中比另一条曲线有优势,当且仅当第一条曲线在PR空间中也比第二条曲线有优势。(这里的“一条曲线比其他曲线有优势”是指其他曲线的所有部分与这条曲线重合或在这条曲线之下。)

图都来自论文An introduction to ROC analysis. Pattern recognition letters

  • (a)和(c)为ROC曲线,(b)和(d)为Precision-Recall曲线。
  • (a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,
  • (c)和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。
  • 可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。

从公式计算中可以看出,ROC曲线中真阳性率TPR的计算公式与P-R曲线中的召回率Recall计算公式是一样的,即二者是同一个东西在不同环境下的不同叫法。当正负样本差距不大的情况下,ROC曲线和P-R的趋势是差不多的,但是当负样本很多的时候,ROC曲线效果依然较好,但是P-R曲线效果一般

6. 什么时候用P-R曲线,什么时候用ROC曲线去评价模型呢?

正例很少的时候,相对于FN更关心FP的时候用P-R曲线。

当正负样本差距不大的情况下,ROC和PR的趋势是差不多的,
但是当负样本很多的时候,两者就截然不同了,ROC曲线能够保持不变,但是P-R曲线上反映出的变化就比较大了。
另一方面,当我们更关心FP(false positives)而不是FN(false negatives)时,也应该用P-R曲线来评价。

参考:


技术交流学习,请加QQ微信:631531977
目录