标签:
关于分类算法我们之前也讨论过了KNN、决策树、naivebayes、SVM、ANN、logistic回归。关于这么多的分类算法,我们自然需要考虑谁的表现更加的优秀。
既然要对分类算法进行评价,那么我们自然得有评价依据。到目前为止,我们讨论分类的有效性都是基于分类成功率来说的,但是这个指标科学吗?我们不妨考虑这么一个事实:一个样本集合里有95个正例,5个反例,分类器C1利用似然的思想将所有的实例均分成正例,分类成功率为95%;分类器C2成功分出了80个正例,3个反例,分类成功率仅83%。我们可以说分类器C2不如C1吗?这就充分表明了,分类成功率掩盖了样本是如何被分错的事实。
那么我们怎么来充分反映分类的好坏呢?一个普遍使用的办法就是报告分类矩阵(又称混淆矩阵),他可以帮助我们更好地理解分类情况,许多的分类评价指标都是基于分类矩阵发展起来的。
当然,分类器在一个数据集上的好坏说明不了任何问题。以一个数据集的表现来评价分类器性能对分类器而言是极端不公正的也是极端不科学的。但是我们这里因为篇幅限制,也只能通过一个数据集来看看分类的好坏。
我们使用一个在信用评分领域里大名鼎鼎的免费数据集,German Credit Dataset,你可以在UCI Machine LearningRepository找到(下载;数据描述)。我们把这个数据分为两部分,训练数据train和测试数据test,我们感兴趣的二分变量是good_bad,取值为{good, bad}。
信用评分指帮助贷款机构发放消费信贷的一整套决策模型及其支持技术。一般地,信用评分技术将客户分为好客户与坏客户两类,比如说,好客户(good)能够按期还本付息(履约),违约的就是坏客户(bad)。具体做法是根据历史上每个类别(履约、违约)的若干样本,从已知的数据中考察借款人的哪些特征对其拖欠或违约行为有影响,从而测量借款人的违约风险,为信贷决策提供依据。
一个完美的分类模型就是,如果一个客户实际上(Actual)属于类别good,也预测成(Predicted)good,处于类别bad,也就预测成bad。但从上面我们看到,一些实际上是good的客户,根据我们的模型,却预测他为bad,对一些原本是bad的客户,却预测他为good。我们需要知道,这个模型到底预测对了多少,预测错了多少,分类矩阵就把所有这些信息,都归到一个表里:
|
真实结果 |
||
+1 |
-1 |
||
预测结果 |
+1 |
真正例(TP) |
伪正例(FP) |
-1 |
伪反例(FN) |
真反例(TN) |
FP和FN就是我们常说的第一类错误与第二类错误,以这四个基本指标可以衍生出多个分类器评价指标。
我们来看看KNN、决策树、naivebayes、SVM、ANN、logistic回归这6种基分类器的分类矩阵。
好了,分类矩阵全部算出来了,现在我们需要考虑的便是应该定义怎样的评价指标了。
常见的分类指标大致有如下几个:
|
真实结果 |
||
+1 |
-1 |
||
预测结果 |
+1 |
真正例(TP) |
伪正例(FP) |
-1 |
伪反例(FN) |
真反例(TN) |
使用这些评价标准可以对分类器进行评估,尤其是其中的准确度或错误率,是比较常用的分类器性能评价标准。(在某些如推荐或信息获取领域还会组合使用precision-recall作为评价指标)但是,所有这些性能评价标准都只在一个操作点有效,这个操作点即是选择使得错误概率最小的点(我们这里选择的是R中默认的分类,与最优阈值下的分类还是有很大差别的)。而且,其中大部分评价标准都有一个共同的弱点,即它们对于类别分布的改变显得不够稳健。当测试集中正例和反例的比例改变时,它们可能不再具有良好的性能,有时甚至不能被接受。
构造一个高正确率(precision)或者高召回率(recall)的分类器不难,但是要保证两者同时成立却是很难的。显然如果任何样本都判为正例,那么召回率很高但是正确率很难保证。构造一个同时使正确率和召回率最大的分类器也是具有挑战性的。
我们来看看各种方法的各个指标情况:(上面是训练集下面是测试集的数据)
method |
FP rate |
specificity |
recall |
precision |
accuracy |
F-score |
logistic |
35.10% |
64.90% |
76.87% |
83.71% |
73.29% |
64.35% |
Test |
36.36% |
63.64% |
76.55% |
84.73% |
73.00% |
64.86% |
ANN |
50.61% |
49.39% |
87.93% |
79.74% |
76.13% |
70.11% |
Test |
58.18% |
41.82% |
86.21% |
79.62% |
74.00% |
68.64% |
SVM |
57.96% |
42.04% |
77.12% |
75.09% |
66.38% |
57.91% |
Test |
58.18% |
41.82% |
80.00% |
78.38% |
69.50% |
62.70% |
naive bayes |
44.49% |
55.51% |
84.32% |
81.11% |
75.50% |
68.39% |
Test |
60.00% |
40.00% |
82.76% |
78.43% |
71.00% |
64.91% |
C4.5 |
37.55% |
62.45% |
86.31% |
83.89% |
79.00% |
72.40% |
Test |
60.00% |
40.00% |
82.76% |
78.43% |
71.00% |
64.91% |
CART |
78.37% |
21.63% |
98.20% |
73.95% |
74.75% |
72.62% |
Test |
85.45% |
14.55% |
96.55% |
74.87% |
74.00% |
72.28% |
KNN |
21.63% |
78.37% |
95.14% |
90.88% |
90.00% |
86.46% |
Test |
54.55% |
45.45% |
82.07% |
79.87% |
72.00% |
65.55% |
将各个指标按降序排列看看哪个方法更好:
可以看到,对于这组非平衡数据,CART分类的结果是很棒的(主要考虑测试集),ANN也有不错的表现,相比之下,在平衡数据里表现不俗的SVM反而表现很差,我们再来看看在业界应用很多的logistic回归的表现:从recall的角度(预测为正例的真实正例占所有的真实正例的比例)来看,logistic回归并不占优,也就是利用这个模型银行决定发放贷款的人群仅占了值得给予贷款的人群的一小部分;再来看precision,从这个角度(预测为正例的比例在真正正例的比例)来看,logistic表现很好,也就是银行估计你不会违约那么你违约发生的可能性真心不大,所以就可靠性来说,这个做法有一定的合理性;再看整个预测的准确性,logistic表现也很好(测试集角度)。可能由于ANN的隐藏结点个数的选择,CART的剪枝不太好把握,所以银行选择logistic模型作为贷款评估是有一定道理的。
现代分类器很多都不是简单地给出一个0或1 的分类判定,而是给出一个分类的倾向程度,比如贝叶斯分类器输出的分类概率。对于这些分类器,当你取不同阈值,就可以得到不同的分类结果及分类器评价指标。我们还可以看到,随着阈值的减小(更多的客户就会被归为正例),recall和1-Specificity也相应增加(也即Specificity相应减少)。那么我们要动态的评价,一个合理的办法就是把基于不同的阈值而产生的一系列recall和Specificity描绘到直角坐标上,就能更清楚地看到它们的对应关系。由于recally和Specificity的方向刚好相反,我们把sensitivity和1-Specificity描绘到同一个图中,它们的对应关系,就得到了传说中的ROC曲线,全称是receiver operating characteristic curve,中文叫“接受者操作特性曲线”。
受试者工作特征曲线 (receiver operatingcharacteristic curve,简称ROC曲线),又称为感受性曲线(sensitivity curve)。得此名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已。接受者操作特性曲线就是以虚报概率为横轴,击中概率为纵轴所组成的坐标图,和被试在特定刺激条件下由于采用不同的判断标准得出的不同结果画出的曲线。(摘自:百度百科)
要分析ROC曲线,就得回到分类矩阵上,我们再来看看分类矩阵:
ROC绘制的就是在不同的阈值p下,TPR和FPR的点图。所以ROC曲线的点是由不同的p造成的。所以你绘图的时候,就用不同的p就行。
上图便是利用logistic模型测算违约率的模型的ROC曲线(训练集),我们可以看到在ROC曲线上会报告两条线:一条实线,代表阈值变化时分类模型给出的TPR与FPR的变化情况;一条虚线,代表随机猜测的TPR与FPR的变化情况。如果实线在虚线之上,那么恭喜你,你的预测模型比胡乱猜测要优秀的。如果在虚线之下,那么你还是放弃你的猜测办法好了。
显然,一个理想的模型会尽可能的处于左上角,这意味着两类错误的都很低。这就告诉我们,可以计算ROC实线上的每一个点与(0,1)的距离,距离最小的那个点对应最佳阈值。我们分类时就应该这么去设置阈值,而非单纯的设置0.5,上图我们可以看出阈值取0.4时比0.5会好一些,我们来看看是不是这样的:
当阈值为0.4时的分类矩阵:
训练集 |
good |
bad |
|
测试集 |
good |
bad |
good |
453 |
94 |
|
good |
114 |
23 |
bad |
102 |
151 |
|
bad |
31 |
32 |
我们还可以利用R算出最优阈值0.4408,此时的分类矩阵(训练集最优)
训练集 |
good |
bad |
|
测试集 |
good |
bad |
good |
451 |
87 |
|
good |
114 |
22 |
bad |
104 |
158 |
|
bad |
31 |
33 |
与0.5时的分类矩阵相比:
训练集 |
good |
bad |
测试集 |
good |
bad |
good |
442 |
86 |
good |
111 |
20 |
bad |
133 |
159 |
bad |
34 |
35 |
可以看到分类效果还是有所改善的。
名称 |
训练集 |
测试集 |
||||
阈值 |
0.5 |
0.4 |
0.44 |
0.5 |
0.4 |
0.44 |
FP rate |
35.10% |
38.37% |
35.51% |
36.36% |
41.82% |
40.00% |
specificity |
64.90% |
61.63% |
64.49% |
63.64% |
58.18% |
60.00% |
recall |
76.87% |
81.62% |
81.26% |
76.55% |
78.62% |
82.29% |
precision |
83.71% |
82.82% |
83.83% |
84.73% |
83.21% |
86.75% |
accuracy |
73.29% |
75.50% |
76.13% |
73.00% |
73.00% |
76.96% |
F-score |
64.35% |
67.60% |
68.12% |
64.86% |
65.42% |
71.38% |
关于ROC下的最优阈值,简单理解下的话,保证TPR同时代价FPR要尽量的小,那么我们建立max(TPR+(1-FPR))的模型,然后选合适的阈值p_0。
这就说明用ROC比用一些静态指标是要好很多的。而且ROC有一个更大的优点,就是可以基于成本效益来判决分类器好坏,比如说银行处在扩张的阶段,它吸纳一个伪客户的后果远比放弃一个真客户的后果要轻,于是我们比较分类器就应该在控制弃真错误的基础上比较谁犯的取伪错误更少来评价。在这样的指导思想下,我们可以判断下图的A与B谁更优秀。这是静态指标肯定做不到的。
ROC曲线是根据与45度线的偏离来判断模型好坏。图示的好处是直观,不足就是不够精确。到底好在哪里,好了多少?一个自然的想法就是对曲线下的面积进行比较,这就传说中的AUC(Area Under the ROC Curve,ROC曲线下的面积),不过也不是新东西,只是ROC的一个派生而已。
回到先前那张ROC曲线图。45度线下的面积是0.5,ROC曲线与它偏离越大,ROC曲线就越向左上方靠拢,它下面的面积(AUC)也就应该越大。我们就可以根据AUC的值与0.5相比,来评估一个分类模型的预测效果(我们这里logistic分类器训练集的auc约为0.78)。但是AUC仅仅给出的是分类器的平均性能值,这是不能代替对整条曲线的观察的。
我们现在来说说ROC曲线的做法。为了画出ROC曲线,分类器必须提供每个样例被判为正例或者反例的可信度的值(在一些文献中称之为score)。如naive Bayes提供了一个可能性,logistic回归中输入到sigmoid函数中的数值或者sigmoid函数的输出值,SVM中输到sign函数里的数值都可以看做分类器预测强度的衡量值。为了画出ROC曲线,首先要将分类样例按照其预测强度排序,先从排名最低的开始,所有排名更低的都被判为反例,所有排名更高的都被判为正例,这就得到了对应的点(1,1);然后,将其移到排名次低的样例中去,如果该样例是正例,那么修改TPR,否则修改FPR;依次做下去,可以得到ROC。
上述过程听起来不是那么的明白,不妨阅读以下下列代码,就会发现一切是那么的一目了然。(以logistic模型考虑客户分类为例)
得到如下图形(与之前R给出的ROC相比是不是几乎一样的):
运行下列代码还可以得到近似的AUC:
这里我解释一下为什么这么算。首先我们回到ROC曲线的定义上,我们可以清楚的看到曲线下方的点都是正例得分超过反例的点。这也再次说明了AUC给出了分类器的平均性能值。于是,利用蒙特卡罗的办法就可以轻松地得到面积。aucs<-replicate(1000,mean(sample(pos.label,1000,replace=T)> sample(neg.label,1000,replace=T)))代码是为了利用bootstrap的办法来看看模拟计算的好坏而写的,可以忽略不看。
(tips:蒙特卡罗算面积的一个很直观的解释.假设你要计算上图的面积,我们可以将这个图片用1*1的纸张打印出来,倒1000颗豆子到纸上(假定豆子全在纸上),那么大数定律告诉我们,落在曲线下方的豆子数/总豆子数可以看做任取一点那一点落在曲线下方的概率=曲线下方的面积/总面积,总面积已知,故求出曲线下方的面积)
我们将logistic回归,人工神经网络(ANN)、支持向量机(SVM)、朴素贝叶斯(naivebayes)的ROC曲线绘制如下(训练数据集):
在看看测试数据集的ROC曲线:
从上图我们可以很容易理解为何业界人士那么喜欢logistic回归作为信用评分的标准了吧,它不仅简单而且好用。
为了精确的比较,我们还是来报告一下AUC:
|
Logistic |
ANN |
SVM |
Bayes |
训练集 |
0.78195 |
0.79782 |
0.60607 |
0.77650 |
测试集 |
0.76075 |
0.69072 |
0.67498 |
0.73241 |
除了ANN可能是我设计的不是那么的合理(隐藏结点取5有些magic number的味道)导致其AUC可能超过logistic而没有超过外,其他的都能看到logistic在AUC指标下表现不俗。但是我们从整个ROC曲线来看。Logistic的优势在于logistic很好的控制住了FPR,所以在两类错误代价不一致时,如何选取还得仔细分析。正如同我们前面说的数据分析是一门艺术而不是一门技术,具体问题还需具体分析。
ROC曲线的所有内容都是分类矩阵提供的,我们可以运用ROC类似的办法来定义一些新的曲线来衡量分类器性能的好坏。我们这里还是先回顾一下分类矩阵:
我们之前在评述静态分类指标时就说过,在某些如推荐或信息获取领域还会组合使用precision-recall作为评价指标。那么我们不妨来看看precision与recall展示到二维空间后评估了什么?合理的解释又是什么?
Precision-Recall曲线,这个东西应该是来源于信息检索中对相关性的评价,用我们的例子来讲,Precision 就是我们决定发放贷款的人群中有多少是会按时还款的,Recall就是所有值得发放贷款的人有多少被银行挑选出来给予服务了。放到检索中来说,Precision 就是检索出来的条目中(比如网页)有多少是准确的,Recall就是所有准确的条目有多少被检索出来了。这也就是为什么IR中很多算法的评估都用到Precision和Recall来评估好坏。
我们来看看logistic回归在测试集上PR曲线的表现:
Logistic回归在训练集上的表现:
与ROC曲线的做法类似,我们这里不再详述PR曲线的做法,我们直接上代码:
我们来看看PR意义下不同分类器的绩效(左训练集右测试集):
我们再一次回到分类矩阵:
考虑lift曲线,意味着我们需要重新加入一个指标:lift。为了叙述的简便,在说lift之前我们引入指标:depth、k。
Precision表明如果采用了分类器,正例的识别比例;而k表明如果不用分类器,用随机的方式抽取出正例的比例。这二者相比自然就解决了如果使用者用分类器分类会使得正类产生的比例会增加多少的问题。这就自然而然的定义了提升值lift:Lift=precision/K,意味着与不利用模型相比,模型的预测能力“变好”了多少。
显然,lift(提升指数)越大,模型的运行效果越好。如果这个模型的预测能力跟似然的结果一样(lift等于1),这个模型就没有任何“提升”了。
光有lift一个指标是不够的,那么还有一个指标是什么呢?depth(有的书称为RPP:正类预测比例,Rate of positive predictions的缩写)。之所以选择depth是因为随着阈值的减小,更多的客户就会被归为正例,也就是depth(预测成正例的比例)变大。当阈值设定得足够的小,那么几乎所有的观测值都会被归为正例(depth几乎为1)——这时分类的效果就跟似然的结果差不多了,相对应的lift值就接近于1。
lift曲线是数据挖掘分类器最常用的方式之一,与ROC曲线不同的是lift考虑分类器的准确性,也就是使用分类器获得的正类数量和不使用分类器随机获取正类数量的比例。
那么在一个合理的depth范围内,我们要寻找最大的提升。这就是比较模型的依据。我们先来看看logistic回归模型的lift图:
一个常用的利用lift图作为模型比较依据的办法:lift图把验证数据集中的观测数据根据它们的分数以升序或降序排列,分数是基于训练数据集估计的响应事件(成功)的概率。把这些分数再细分成10分位点,然后对验证数据集中的每个10分位点计算和图示成功的预测概率。如果这些成功的预测概率与估计概率具有相同的顺序(升序或降序),那么模型就是有效的。 我们以下图为例:
我们来看看lift意义下不同分类器的绩效(左训练集右测试集):
当然这里有必要指出的是lift这个指标就是作为单纯的静态指标也是很常用的,而且可以这么说lift作为静态指标比作为这样的动态指标更常用,毕竟比起用哪一类模型我们更关心确定的那一个模型的好坏。通常来说lift大于2就说明分类效果可以了。但是对于有偏数据来说,似然估计的准确率已经很高了,希望lift达到2或者更高基本不太现实。
有了lift的基础,我们要说的增益曲线就变得异常简单了,lift曲线不是以lift作为评价指标嘛,我们换成precision作为评价指标,画precision-depth曲线就是传说中的gains曲线了。
既然gains曲线选择了precision作为纵轴,那我们选recall可不可以呢?当然可以,传说中的lorenz曲线就是他了。
lorenz曲线的横轴就是lift曲线中涉及到的深度depth,也就是:将样本的预测为1的概率从大到小排序后,取前百分之几。通常会简化成十分位点,0%,10%,20%,...,90%,100%。而曲线的纵轴其实就是相对应的TPR。形象地说,就是我们面对着一堆人(1000个),这堆人里面有20个坏人,我们的目标就是抓坏人。通过模型计算,我们把这堆人按照可能是坏人的概率从大到小地排了队,然后我们抓取前一百名,在这前一百名里面,可能就有13个坏人了(因为这一百个人的是坏人的概率比较高嘛),也就是说我们只抓取10%的样本,但是抓到了65%的目标。从lift的角度也可以很好地理解这种提升效果,而lorenz则更形象地展示了这种投入产出比的含义。
以上提到的ROC、Lift、Gains、Lorenz,都是基于混淆矩阵及其派生出来的几个指标。如果愿意,你随意组合几个指标,展示到二维空间,就是一种跟ROC平行的评估图。
R提供了各种各样的函数来实现分类的绩效评估。我们为了保持行文的一贯性,我们使用鸢尾花数据(仅考虑后两种花的分类)SVM模型来说说R是如何实现绩效评估的。
有些指标在另一群人的眼中是这样的:
我们来看看最熟悉的分类矩阵(data仅为鸢尾花的51到150行的数据):
之后是ROC图:
计算AUC:
计算ROC意义下的最佳阈值:
绘制PR曲线:(默认以加载ROCR包,下同)
绘制lift曲线:
绘制Gain曲线
绘制Lorenz曲线:
除此以外,你还可以尝试Sensitivity/specificity曲线(试着解释一下它)
前面说了那么多,我们考虑GermanCredit Dataset这个例子,把我们所说的东西的含义简单的总结一下。
我们所说的增益gain意味着从30%的人里抓到了50%的欺骗者,这就是gain曲线(0.3,0.5)这一坐标点的含义。对角线意味着利用似然想法随意抓人的收益。
我们所说的提升lift意味着从30%的人里抓,抓到5个,比随便抓,抓到3个要好了5/3=1.7,这就是lift曲线(0.3,1.7)这一点的含义
我们所说的ROC曲线意味着从30%的人里面抓到了欺骗者的50%(5/10),抓错了好人20%(4/20),这就是ROC曲线上(0.2,0.5)的含义。对角线意味着胡乱抓人(每人都有50%的可能是欺骗者)的情况。
Lorenz曲线与K-S指标见下图:
(上图的坐标轴标注不是很准确:红线是lorenz bad,蓝线是lorenzgood)
这次不提供further reading,这篇文章参考但不限于下列文献:
百度百科:ROC曲线
波波头一头:二分类模型性能评价2.0(ROC曲线,lift曲线,lorenz曲线)
胡江堂:分类模型的性能评估系列文章(混淆矩阵、ROC和AUC、lift和gain)
不周山:分类器评价、混淆矩阵与ROC曲线
注:这篇文章所用的数据,代码你也可以点击这里下载
转自:http://blog.csdn.net/yujunbeta/article/details/18138957#comments
标签:
原文地址:http://www.cnblogs.com/payton/p/4281099.html