本帖最后由 其实...我还小 于 2016-3-9 10:21 编辑 9 s9 T: O* @8 m$ L# ~
( f0 J: F/ j. E, |( l( K
每个建模人都应该知道的7种模型误差评估方法
/ N! ]. X; n! q/ n2 Q% }
0 c6 X3 P+ x' n ], s0 v6 }3 H/ g$ v
介绍: 预测模型是基于结构性反馈原则的一种模型,也就是说,你建立了一个模型,在不断地指标的反馈中修正模型,直到预测结果达到一个理想的精确度。对于指标的评估给出了对于模型预测能力的一种很好的解释。指标评估一个很重要的方面就是它对于模型结果的区分能力。
0 T( d S5 S1 u* y* \很多“小白”分析师,甚至都不会去检查模型的精度,一旦他们建立好了模型就会立马对未来数据进行预测,这种行为不推荐,因为这不科学。 2 G( c# u5 q# m* E+ A Z5 o' [
简单的来讲,我们并不是为了建立一个预测模型而建模,重要的如何建立或找一个可以对于样本数据给出高精度预测的模型。所以,模型精度是首要的,这可比得到预测数据重要得多。 ( w3 W9 W7 G- M8 M3 ?1 C$ t
我们的行业里,我们会考虑不同的指标来对模型进行评估。我们选择指标完全取决于模型的类型和模型建立计划。在你建立模型之后,以下的七个指标会很好的帮助你评估模型。考虑到交叉验证的受关注度在提升,所以本文中也会提到这个准则。
: n8 i, j' M0 @. [* t( ]4 P2 V目录:2 Q0 U7 I: R" b* e( j* ]
1.混淆矩阵 2.增益表和提升表 3.Kolmogorov Smirnov表 4.AUC-ROC 5.Gini系数 6.和谐-不和谐比(Concordant – Discordant Ratio) 7.均方根误差(RMSE) 8.交叉验证(注:非指标)
, g% o0 O! T, A5 e热身:预测模型的种类当我们说起预测模型的时候。我们讨论的可以是回归模型(连续输出),或者是分类模型(名义输出或者二进制输出)。对于这些模型的指标评估是不一样的。
9 a% L/ C) r* A5 o: ]6 ^在分类问题中,我们使用两种算法(基于其输出值的种类来选择) 1.类输出(Class output):类似于SVM和KNN的算法创建类输出结果。比如:在二进制分类的问题,结果不是0就是1。但是,今天我们所说的算法可以把这种类输出变成概率。但是这些算法却没能被统计界很好的接受。 2.概率输出(Probability output)就像Logistic 回归、随机森林、梯度下降、AdaBoost等算法可以给出概率输出结果,将概率型输出转化为类输出,只是去创建一个阈值的问题。 3.在回归分析中,我们没有这样类型不一致的结果。输出值都是连续且不需要进一步处理的。 % q; {+ T0 L; H% `) g( a5 M
举例说明对于分类模型的指标评估的讨论,我用了我在Kaggle的BIC挑战问题中的预测。这个问题的结论和我们的讨论无关,可是,本文中需要对于训练集最后的预测这部分内容。这里的预测利用一个0.5的阈值将概率型输出转化为类输出。
, t! I! b8 a, n3 ^3 D6 W g1.混淆矩阵混淆矩阵是一个\(NXN\)的矩阵,其中\(N\)是被预测类的个数。对于我们的问题,我们选\(N=2\),所以我们得到了一个\(2X2\)矩阵。以下是一些关于混淆矩阵的定义: 精确度(Accuracy):正确的预测再所有预测中所占的比例。 阳性预测值或准确性(Positive Predictive Value or Precision):被正确识别的阳性案例所占比例。 阴性预测值(Negative Predictive Value):被正确识别的阴性案例所占比例。 敏感度与回忆(Sensitivity or Recall):被正确识别的实际阳性案例所占比例。 特异性(Specificity):被正确识别的实际阴性案例所占比例。
1 H0 R. C# z. }4 [8 u2.增益表和提升表 增益表和提升表是用来检测概率的秩序。以下是建立增益表/提升表的步骤。 第一步:计算每一个观测结果的概率。 第二步:按照降序对概率进行排序。 第三步:以总观测值的10%为标准分组并建立十位数。 第四步:计算对Good(应答者),Bad(非应答者)及全部,在十分位数的反应速率。 你会得到下表(需要自己绘图): " w3 y7 Z9 `7 v m
这是一个资讯非常丰富的表。累积增益表,累积Right的百分比和积累Population。如下图:
. H4 k2 q. t( n/ x O+ i! v2 _: \这个图表告诉我们,应答者(responders)与非应答者(non-responders)的分离程度。例如,在第一个十分位数占有10%的总体,有14%的应答者。这意味着我们在第一个分位数有140%提升。 5 P8 y* E; k# K$ D/ H
到底在第一个十分位数上,我们最大的提升可以达到多少呢?从第一个表我们可以知道,总共的应答者数是3850,而第一个十分位数会包含543个观测值,所以,第一阶段的最大提升量为543/3850~14.1%,所以这个模型的表现几乎完美。 1 Y; P2 A" v7 A
现在,让我们绘制提升曲线,提升曲线是总提升和总体百分比关系的图形。注意到,对一个随机模型,它总是保持稳定在100%,如下图: 6 b: ?9 P- J" O$ t: P1 K+ m' s2 o: N
你也可以绘制十分位数上wise 提升图:
, I: Z2 J* a, R8 V& S; q3 v7 B这幅图告诉了你什么?它说明了这个模型在前七个十分位数前都表现良好。此后的每个十分位数都有向非应答者倾斜。任何一个提升@十分位数(left@decile)大于100%(在第三个十分位数达到最小值,再第七个十分位数达到最大值)的模型就是一个好模型。否则,你就要首先考虑过采样(over sampling)。 7 s( x9 f) ` a" [* G* m1 c
提升图/增益图广泛用于竞选定标问题。在一场竞选中,它可以告诉我们直到哪一个十分位数我们可以确定目标,并且它可以告诉你,在新目标的基础上,你预期的回应数量是多少。
7 i3 y7 z( ]4 _- { V& q- |" j" f9 N" A
3.Kolmogorov Smirnov 表K-S(Kolmogorov Smirnov)可以对分类模型的表现给出评价。更准确的说,K-S 是衡量对于正分布和负分布的分离程度。如果,将全部总体分为两个分组的情况下,所有的阳性值都包含在其中一组,阴性值都包含在另一个组,那么K-S的值就是100.
! b) \) r) M, e. H6 A# L4 D' z( H* K另一方面,如果模型中不能区分阳性值和阴性值,就好像模型随机从总体选取值,K-S为零。在大多数分类模型中,K-S的取值在0-100之间,而且评分越高说明模型对于阳性值和阴性值的分类情况越好。 如下表: , F* [' n+ A0 J! R. |# v% _7 S
* a0 D8 R! C$ d
我们还可以绘制Good和Bad积累百分比最大值分割,以下就是样本绘图: 3 X* C; X1 s( q% D+ e$ P% s5 `
我们以上讲的指标都是用于分类问题。目前,我们讲了混淆矩阵,提升表和增益表、Kolmogorov Smirnov 表,下面让我们来讲一些更重要的指标。
# J0 B n- U- x0 F2 O- Z5 @- @( c8 C3 M, t# X3 ^
4.ROC曲线下的面积(AUC-ROC)这个指标也是业内非常受欢迎的指标,用ROC曲线最大的优点就是它独立于响应者反应度的比例。从后面的讲解中我们可以更清楚了了解到AUC-ROC。 9 {9 F' D! s" x6 R# I7 Y
首先我们来了解一下什么是ROC(Receiver operating characteristic)曲线。如果我们下面的混淆矩阵。我们观察到对于一个概率模型,我们会从不同的指标中得到不同的值。
8 K# D7 S* e! v) n. A+ w; F# C因此,在不同的灵敏度下。我们会得到不同的特异度(specificity),两种变化如下:
) A- g8 N/ y2 k- l* SROC曲线是绘制灵敏度与(1—特异度)之间的关系的图形。(1—特异度)就是我们所知的假阳性率,灵敏度就是我们所知的真阳性率。以下就是ROC再本情况下的表现。
0 V- E6 ~2 A/ }4 B让我们来举一个阈值为0.5(参考混淆矩阵)的例子。以下就是混淆矩阵。 # j0 z4 j- C7 l( L0 X
就像你看到的,灵敏度在阈值为99.6%和(1-特异度)是60%。这个坐标(coordinate)就成为了我们ROC曲线上的点。我们利用曲线下的面积将这条曲线转换为一个数字,就得到了AUC。
( h8 Z( z7 ?! V) J/ r9 g注意到正方形的面积是\(1X1\),所以AUC本身就是曲线下面积和整体面积的比率。对于我们的问题,我们得到的AUC ROC是96.4%。下面我们给出一些经验法则(thumb rules):
0 H4 d% ^1 K5 `5 g.90~1=excellent(A) .80~.90 = good (B) .70~.80 = fair (C) .60~.70 = poor (D) .50~.60 = fail (F) o( z0 v7 |' [' n7 p& m
我们看到,我们这个模型是在excellent这个区域的。但是,这可能只是过度拟合的结果。对于这样的情况,我们进行in-time与out-of-time验证。 6 m# A3 K1 n Y# X( u2 \! T
注意事项: 1.对于我们以类输出,给出输出结果的模型,会被表示成ROC曲线上的一个点。 2.对于不能和其他模型比较的模型,我们只能用单一的指标进行判定,不可用多指标。例如,参数为(0.2,0.8)的模型与参数为(0.8,0.2)的模型,可能是同一个模型,所以这样的指标不能进行直接的比较。 3.对于概率模型,我们很幸运的可以得到单一数字,那就是AUC-ROC。但是,我们需要看整条曲线才能下结论,因为对于一个模型而言它可能在某些区域优于其他模型,而其他地方劣于其他模型。
# V- ~5 c1 T7 c( y) _6 z2 L( l' tROC的优势:
7 {9 P0 b- m5 R为什么要使用ROC,而不用其他的指标(例如:提升曲线)? " a) q% l6 ?1 o" f1 d) c. x2 ]
提升是依赖于应答者在总体中的比例。因此,如果应答者再总体中的比率改变了,那么同样的模型会个出不同的提升图。一个解决方案就是,利用真实提升图(在每个十分位数找到提升图和模型完美提升图之间的比例)。但是这种方法只对商业行为(business)具有意义。 1 l% Z; F, l" {9 H4 \0 T
从另一个方面来讲,ROC曲线几乎与应答者比率无关。这因为它的两条轴是通过混淆矩阵的列变换得到的。X轴和Y轴的分子和分母只会在应答者比例提升的基础上,变化很小。
/ W+ [ ~$ H$ z* x- u* L" z5.Gini 系数Gini系数通常用于分类问题。基尼系数可以从AUC-ROC直接导出。Gini系数只是在ROC曲线和对角线与三角形之上围成的面积。以下就是所用的公式: \(Gini = AUC-1\) ! s4 O) q( x: x
Gini系数在60%以上的是好模型。对于我们这个模型,Gini系数是92.7% - t! Z6 o) I( n
6.和谐-不和谐比(Concordant – Discordant Ratio)接下来,我们再介绍一个对于分类问题的预测的重要指标。为了方便理解,我们假设3个学生有今年有可能通过(测验,毕业等)。 以下是我们的预测: A – 0.9
2 I4 v2 ?1 j6 w- F2 FB – 0.5
. w& N s0 I8 D) |* g: ?, O/ H/ AC – 0.3 现在让我们来构想这个问题,如果让我们从这三个学生中取出一对,我们可以有几种取法,答案是显而易见的,我们有三种取法,AB,BC,CA。现在,在年末的时候,A和C通过了,但是B没有通过。不,我们选择所有的配对,去找应答者和其他的非应答者组成的配对,我们可以得到几对?
N/ W- K, I2 }& a7 D1 U3 g1 Y8 N我们可以找到两对,AB和BC。对于这两对,和谐的那一对就是应答者概率高于了非应答者,同理可得到不和谐的那一对。如果我们找到的两对概率相同,那么我们称为平局。现在看看我们刚才想的问题:
( s' Y! i: T( m7 ?AB – 和谐 & k7 Z4 ~) X+ B$ z/ E4 f
BC – 非和谐 4 f. u! T" j5 c( u7 N O$ y7 n% x
因此,在这个例子中,我们有一半的不和谐情况。和谐情况所占比例大于60%就是好模型。这个指标通常上不会用于“决定要将多少客户设定为目标”这种问题,而用于模型预测能力的体现。对于“决定要将多少客户设定为目标”问题我们会使用KS/提升表。 & f5 P e8 b, S; i% m
7.均方根误差(RMSE)RMSE是在回归问题中广泛应用的一种评价指标。它有一个基本假设,那就是误差无偏且服从正态分布。以下是几个我们在使用RMSE时需要注意的几个点: 1.“平方根”使这个指标可以很好的显示出较大的偏差。 2.“平方”本质上使得这个指标可以给出一个更稳健的结果,可以防止正向误差和负向误差被相互抵消。换言之,这个指标可以恰当的表现出误差项的合理区间。 3.它可以避免在数学运算导致的较高的绝对误差。 4.当我们有很多样本的时候,利用RMSE来重新构建误差项的分布会更为可靠。 5.RMSE会受到离群值较大的影响,因此我们要确保离群值已经从我们的数据中提出了之后才可以利用这个指标评估。 6.相比于平均绝对误差,RMSE具有高权重,对误差给更大的惩罚。 RMSE指标: \(RMSE=\sqrt{\frac{\sum_{i=1}^{N}(Predicted_{i}-Actual_{i})^{2}}{N}}\) 3 F( K1 U$ k' E/ Q( ^
其中,N是观察数据的重量。
; p) j1 U% f7 G/ b+ ]以上七个指标,都是用于检测模型的表现。这七个方法都是在数据科学中统计显著。但是,在机器学习中,我们更注重模型的强健的方法来选择模型。对,我们将要讨论(Cross-Validation)。
" ~" P) W! I' |" }: ?- d0 ]$ h尽管Cross-Validation不是一种我们通常谈及到的指标方法。但是,Cross-Validation可以让我们对评价模型的表现给出足够的,且有启发性的结果。
" w9 ~7 B1 d3 | S% s" g8.交叉验证(注:非指标)对于TFI竞赛而言,一下是我的三个结论和评分(越低越好):
0 V8 E8 g9 @9 S% K你会注意到,第三行得到的评分最低,但是私人排名最高。在“submission_all.csv”中有多余20个模型,但是我最终还是选择了“submission_all.csv”最为最后的输入行(表现的非常好)。是什么导致了这种现象?这种公共和私人排行榜是由过度拟合造成的。
$ z. ~/ t) x$ f% @% p' N$ s过度拟合,当你的模型很复杂,它就开始包含噪声(无用的信息),这只会使模型的精确度下降。 8 u/ l; t/ J L6 O; b% e
在接下来的部分中,我们会讨论,怎样才能判定模型是否结论是否是过度拟合或在我们知道知道精度检验结果之前。 ( ~2 C( {( r, @
概念:Cross Validation Cross Validation是对任何种类的数据模型都很重要。简单的来说,留下一个你没有用于训练模型的样本,再完成模型前用它来测试模型。 ( g, \9 I" I+ Q, \
以上的图告诉了我们,如何用in-time 样本完成对模型的验证。我们简单的将总体分为两个样本,用其中一个样本建模,用余下的那部分用于in-time检验。
3 R3 E- y6 ^3 p9 f+ q! x3 D" B以上的方法会有弊端么? 6 G# W1 ^; w3 h1 ~8 {. ?
我相信,这个方法的弊端就是我们失去因为需要训练模型,失去了一部分很好的样本。所以模型会有很强的偏向性,这对于系数的评估的影响特别大。所以,接下来还有什么好的选项么?
5 E4 u; [! k( O- V4 l# D1 L假设,我们将训练总体分为50:50,用第一部分来训练模型,用第二部分来验证模型。之后我们用。第二部分来做模型的训练,第一部分来测试模型,这样,我们就用了全体样本来进行了模型训练,但是,是一半一半来的。这样就可以降低了由杨门选择范围引起的偏差,可是,只能用更少的样本去训练模型。这种方法就只我们所知的,2-折(2-fold)交叉验证法。 6 v+ d: q- i& n3 e1 N9 s0 |6 D7 w( R
K-折交叉验证 让我们从最后的这个例子中来从2-fold推理出k-fold交叉验证。现在我们用图例来解释一下k-折验证是怎样运行的。 : [. P& Q' V% R# ?
这就是7-折的交叉验证。
7 r) F; e' H' _2 Z模型的背后隐藏着什么呢?我们将总体样本分为7个。现在,我们用六个样本(绿色的箱子)用于和另一个样本(灰色的箱子)用于验证。之后,在第二次迭代的时候,我们用不同的样本作为验证。在七次迭代中,我们都充分利用了每一个样本并且用它做了验证。这样我们就可以,尽可能的减少由我们选择样本引起的偏差,并减少了预测出结果的方差。一旦我们做出了这七个模型,我们就可以利用误差项来找出,哪个模型是最好的。 * ]& m f1 R& [ z# G+ h, o- C
交叉验证时怎么样帮我们找到最好的模型(非过度拟合): K-折交叉验证广泛应用于检测模型是否过度拟合。利用评价模型表现的参数在k次建模的过程中都差不多,而且这个指标的均值是否最高的。那么,在Kaggle比较中,你就可以依靠交叉验证的评分而不依靠Kaggle公共评分。这种方法会确保公共评分的非偶然性。 8 d/ A3 p9 O9 d/ B, E& E
如何在模型中应用K-折交叉验证方法? K-折交叉验证在R语言和Python是非常相似的,以下是Python程序: from sklearn import cross_validation model = RandomForestClassifier(n_estimators=100) #Simple K-Fold cross validation. 5 folds. #(Note: in older scikit-learn versions the "n_folds" argument is named "k".) cv = cross_validation.KFold(len(train), n_folds=5, indices=False) results = [] # "model" can be replaced by your model object # "Error_function" can be replaced by the error function of your analysis for traincv, testcv in cv: probas = model.fit(train[traincv], target[traincv]).predict_proba(train[testcv]) results.append( Error_function ) print out the mean of the cross-validated results print "Results: " + str( np.array(results).mean() ) , p5 j" N. e/ F6 Z3 k1 H6 f
在模型建立中,我们如何选择K? 这是一个复杂的问题,但是我们有一个权衡的方法。 对于较小的K,我们会有更高的由选择引起的误差,但是模型表现(预测)的方差会较小。 对于较大的K,则相反。 想象一下极端的例子: K=2:我们只分两个样本,这和我们刚才讲过的50-50的模型非常相似,这里我们建立模型,每次只能依靠总体中50%的样本。但是对于在验证时我们就会有一个非常大的总体,这样就使得模型表现出的误差是非常小的。 K=观察值数量n:这就是我们通常所说的“留下一个(观察值)用于检验”。我们会有n个样本,建模会重复n次,只留出一个观察值做交叉验证,因此,我们的模型,由选择引起的误差就会很小,但是模型表显得误差就会很大。 总体来说K=10,对于大部分问题都是适用的。
; _7 z3 b) [1 G0 Y结尾注: 测量训练样本的表现是没有意义的。留下一批in-time数据是浪费行为。K-折交叉验证可以在很好的范围内尽可能的降低由选择引起的模型误差。此外,在这篇文章中所涵盖的指标是在一些分类和回归问题的评价最常用的指标。在分类和回归问题中,你经常使用哪些指标?你在分析之前,用过交叉验证么?
' o0 }) T! U4 c6 S; \% t5 t) B3 X9 w& }9 N) c
r4 F0 I1 a* X' _3 o) V/ S数学中国翻译,禁止转载 " g6 b$ n* T- s( m$ f
6 B% F/ D; Z- j) r
! a, r- ]4 w, P& g2 z6 m& E7 ]6 ~; o$ P# S- K* n
, w' m D9 _# N. @. F( B: Y! d# V4 D/ a
- H9 O. X( U |
; S8 r# w, ~ T1 a! ~: K% I' z
|