参考:
ROC和AUC介绍以及如何计算AUC
多分类下的ROC曲线和AUC
ROC曲线
首先ROC分析的是二元分类模型,也就是输出类别只有两种值的分类模型。对于其他的多类分类模型可以做相应的转换,本文后面再作分析。
ROC曲线的特点:
- ROC曲线的横轴是False postive rate,纵轴是True positive rate
- 一个特定分类模型在一个测试数据集上只会得到一个FPR和一个TPR,也就是对应ROC曲线上的一个点
- 我们通过在一个输出二元类概率的学习器上设置不同的threshold来得到不同的分类模型,也就可以得到多个ROC曲线上的点。一个threshold是在概率上区分正例和负例的边界值。
- 第一个点,(0,1),即FPR=0, TPR=1,这意味着FN(false negative)=0,并且FP(false positive)=0。Wow,这是一个完美的分类器,它将所有的样本都正确分类。第二个点,(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。第三个点,(0,0),即FPR=TPR=0,即FP(false positive)=TP(true positive)=0,可以发现该分类器预测所有的样本都为负样本(negative)。类似的,第四个点(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好。
下面以sklearn为例说明如何绘制ROC曲线图
#coding=utf-8
import numpy as np
from sklearn.metrics import roc_curve
from matplotlib import pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
y_true=np.array([1,1,0,0,1])
y_scores=np.array([0.5,0.6,0.55,0.4,0.7])
#pos_label指明正例的类标记是什么
fpr,tpr,thresholds=roc_curve(y_true,y_scores,pos_label=1)
print(fpr)
print(tpr)
print(thresholds)
xmajorLocator = MultipleLocator(0.5) #将x主刻度标签设置为0.5的倍数
ymajorLocator = MultipleLocator(1/3.0) #将此y轴主刻度标签设置为1/3的倍数
plt.plot(fpr,tpr)
plt.gca().xaxis.set_major_locator(xmajorLocator)
plt.gca().yaxis.set_major_locator(ymajorLocator)
plt.xlabel("FPR")
plt.ylabel("TPR")
plt.show()
Console output:
[0. 0. 0.5 0.5 1. ]
[0.33333333 0.66666667 0.66666667 1. 1. ]
[0.7 0.6 0.55 0.5 0.4 ]
[Finished in 67.1s]
我们首先将threshold设置为1,得到点(0,0)。然后将预测的类的概率从到小排序,依次作为threshold,相应的依次对每个实例作如下操作:如果该实例是正例,则曲线沿着y轴上升1/m_pos个长度;如果该实例是负例,则曲线沿着x轴向右走1/m_neg个长度(m_pos和m_neg分别代表正例的个数和负例的个数)。最终将threshold设置为0,得到点(0, 0),将所有的点连接起来就是ROC曲线。当threshold取值越多,ROC曲线越平滑。
AUC
AUC(Area Under Curve)被定义为ROC曲线下的面积,显然这个面积的数值不会大于1。又由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。
在python中计算AUC
from sklearn import metrics
auc=metrics.auc(fpr,tpr)
AUC的含义
根据(Fawcett, 2006),AUC的值的含义是:
The AUC value is eauivalent to the probability that a randomly chosen example is ranked higher than a randomly chosen nagative example.
首先AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值。当然,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。
为什么使用ROC
既然已经这么多评价标准,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线5的对比:
在上图中,(a)和(c)为ROC曲线,(b)和(d)为Precision-Recall曲线。(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,(c)和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。
多类分类下使用ROC&AUC
由于ROC曲线是针对二分类的情况,对于多分类问题,ROC曲线的获取主要有两种方法:
假设测试样本个数为m,类别个数为n(假设类别标签分别为:0,2,…,n-1)。在训练完成后,计算出每个测试样本的在各类别下的概率或置信度,得到一个[m, n]形状的矩阵P,每一行表示一个测试样本在各类别下概率值(按类别标签排序)。相应地,将每个测试样本的标签转换为类似二进制的形式,每个位置用来标记是否属于对应的类别(也按标签排序,这样才和前面对应),由此也可以获得一个[m, n]的标签矩阵L。
例如对于一个规模为10的测试样本,类别个数为3的矩阵P
对应的矩阵L为
方法1:每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。第一种方法也叫作one-vs-rest。比如说是前面的三元分类(A,B,C)问题,把A看作一类,BC合起来看作一类,然后对预测结果做正常的二元ROC&AUC;下面把B看作一类,AC合起来看成一类,再得到一个ROC&AUC,最终可以得到三个ROC&AUC。把这三个数值取均值就可以得到这个三元分类的ROC&AUC。
方法2:首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。