本文主要介绍几种常用的用于分类的性能评估指标,同时介绍如何绘制ROC曲线以及计算AUC值的便捷方法。最后再附上一个绘制ROC曲线和计算AUC的Python源码实现。
Precision和Recall
首先我们来看看下面这个混淆矩阵:
pred_label/true_label | Positive | Negative |
---|---|---|
Positive | TP | FP |
Negtive | FN | TN |
如上表所示,行表示预测的label值,列表示真实label值。TP,FP,FN,TN分别表示如下意思:
- TP(true positive):表示样本的真实类别为正,最后预测得到的结果也为正;
- FP(false positive):表示样本的真实类别为负,最后预测得到的结果却为正;
- FN(false negative):表示样本的真实类别为正,最后预测得到的结果却为负;
- TN(true negative):表示样本的真实类别为负,最后预测得到的结果也为负.
根据以上几个指标,可以分别计算出Accuracy、Precision、Recall(Sensitivity,SN),Specificity(SP)。
$$Accuracy = \frac{TP+TN}{TP+FP+TN+FN}$$
$$Precision = \frac{TP}{TP+FP}$$
$$Recall = \frac{TP}{TP+FN}$$
$$SP = \frac{TN}{TN + FP}$$
- Accuracy:表示预测结果的精确度,预测正确的样本数除以总样本数。
- precision,准确率,表示预测结果中,预测为正样本的样本中,正确预测为正样本的概率;
- recall,召回率,表示在原始样本的正样本中,最后被正确预测为正样本的概率;
- specificity,常常称作特异性,它研究的样本集是原始样本中的负样本,表示的是在这些负样本中最后被正确预测为负样本的概率。
在实际当中,我们往往希望得到的precision和recall都比较高,比如当FN和FP等于0的时候,他们的值都等于1。但是,它们往往在某种情况下是互斥的。例如,有50个正样本,50个负样本,结果全部预测为正样本,那么TP=50,FP=50,TN=0,FN=0,按照上面的公式计算,可以得到正样本的recall却为1,precision却为0.5.所以需要一种折衷的方式,因此就有了F1-score。
$$ F1-score = \frac{ 2 \times recall \times precision}{ recall + precision}$$
F1-score表示的是precision和recall的调和平均评估指标。
另外还有一个指标,即MCC,该指标对于不均衡数据集的评估非常有效,公式如下:
ROC曲线
ROC(receiver operating characteristic),平面的横坐标是false positive rate(FPR)假阳率,纵坐标是true positive rate(TPR)真阳率。ROC计算过程如下:
- 首先每个样本都需要有一个label值,并且还需要一个预测的score值(取值0到1);
- 然后按这个score对样本由大到小进行排序,假设这些数据位于表格中的一列,从上到下依次降序;
- 现在从上到下按照样本点的取值进行划分,位于分界点上面的我们把它归为预测为正样本,位于分界点下面的归为负样本;
- 分别计算出此时的TPR(Recall)=TP/P和FPR(1-SP)=FP/N,然后在图中绘制(FPR, TPR)点。
从上往下逐个样本计算,最后会得到一条光滑的曲线 。
然而,千言万语都不如下面这幅图懂得快:
AUC计算
AUC(area under the curve)就是ROC曲线下方的面积,取值在0.5到1之间,因为随机猜测得到额AUC就是0.5。面积如下图所示,阴影部分即为AUC面积:
AUC的几种解释(来自【Interpreting the AUROC】):
- The expectation that a uniformly drawn random positive is ranked before a uniformly drawn random negative.
- The expected proportion of positives ranked before a uniformly drawn random negative.
- The expected true positive rate if the ranking is split just before a uniformly drawn random negative.
- The expected proportion of negatives ranked after a uniformly drawn random positive.
- The expected false positive rate if the ranking is split just after a uniformly drawn random positive.
下面来介绍下它的计算方法,AUC的计算主要有以下三种。
第一种:积分思维。这也是在早期机器学习文献中常用的AUC计算方法。从积分的思想中演化而来的。假如我们的测试样本有限,那么我们得到的AUC曲线必然是呈现阶梯形状。因此,计算的AUC也就是这些阶梯下面的面积之和(有没有想起以前学高数时的积分面积哈)。我们可以这样来计算,首先把score值进行排序,假设score越大,此样本属于正类的概率就越大。然后一边扫描一边计算就可以得到我们想要的AUC。但是,这样做会有个缺点,当多个测试样本的score值相等时,我们调整一下阈值,得到的不是往上或者往右的延展,而是斜着向上形成一个梯形。此时,就需要计算这个梯形的面积,这样是比较麻烦。 简单的用代码描述下
1 | auc = 0.0 |
第二种:Mann–Whitney U test(MWW)。关于AUC还有一个很有趣的性质,它和Wilcoxon-Mann-Witney Test类似(可以去google搜一下),而Wilcoxon-Mann-Witney Test就是测试任意给一个正类样本和一个负类样本,正类样本的score有多大的概率大于负类样本的score。有了这个定义,就可以得到了另外一中计算AUC的方法:计算出这个概率值。我们知道,在有限样本中我们常用的得到概率的办法就是通过频率来估计之。这种估计随着样本规模的扩大而逐渐逼近真实值。样本数越多,计算的AUC越准确类似,也和计算积分的时候,小区间划分的越细,计算的越准确是同样的道理。具体来说就是: 统计一下所有的 M×N(M为正类样本的数目,N为负类样本的数目)个正负样本对中,有多少个组中的正样本的score大于负样本的score。当二元组中正负样本的 score相等的时候,按照0.5计算。然后除以MN。实现这个方法的复杂度为O(n^2 )。n为样本数(即n=M+N),公式表示如下:
第三种:该方法和上述第二种方法原理一样,但复杂度降低了。首先对score从大到小排序,然后令最大score对应的sample的rank值为n,第二大score对应sample的rank值为n-1,以此类推从n到1。然后把所有的正类样本的rank相加,再减去正类样本的score为最小的那M个值的情况。得到的结果就是有多少对正类样本的score值大于负类样本的score值,最后再除以M×N即可。值得注意的是,当存在score相等的时候,对于score相等的样本,需要赋予相同的rank值(无论这个相等的score是出现在同类样本还是不同类的样本之间,都需要这样处理)。具体操作就是再把所有这些score相等的样本 的rank取平均。然后再使用上述公式。此公式描述如下:
这三种方法,第一种比较好理解,后面两种确实不太好理解,先记下,慢慢理解。
源码
最后,附上ROC曲线绘制代码。下面使用的思想类似积分,但是求得是AUC的近似值,忽略了梯形部分,Code如下:
依赖库:
- numpy
- matplotlib
1 | # -*- coding: utf-8 -*- |
对于ROC曲线绘制中的参数,输入的第二个参数是类别标签(如,+1,-1形成的文件,每行表示一个样本的真实类别);第一个参数则是由模型训练出来的预测强度,如Adaboost对样本i预测的结果为0.67,对i+1个样本预测的结果是0.3,等等,每行一个,格式和classLabels一样。最后绘制ROC曲线的同时,也在输出ROC曲线下方的AUC面积。
参考文献
[1] https://en.wikipedia.org/wiki/Receiver_operating_characteristic
[2] http://blog.csdn.net/chjjunking/article/details/5933105
[3]《Machine Learning in Action》
[4] https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test
[5] Understanding ROC curve
[6] http://stats.stackexchange.com/questions/145566/how-to-calculate-area-under-the-curve-auc-or-the-c-statistic-by-hand