模型评估与选择
模型评估与选择
误差
在分类任务中,通常把错分的样本数占样本总数的比例称为错误率(error rate)。比如 m 个样本有 a 个预测错了,错误率就是a/m
;与错误率相对的有精度(accuracy),或者说正确率,数值上等于 1-错误率。
更一般地,通常会把模型输出和真实值之间的差异称为误差(error)。在训练集上的误差称为训练误差(training error)或者经验误差(empirical error)。而在新样本上的误差则称为泛化误差(generalization error)。我们希望模型的泛化误差尽可能小,但现实是,我们无法知道新样本是怎样的,所以只能尽可能地利用训练数据来最小化经验误差。
但是否经验误差小,泛化误差就一定小呢?这不是一定的,如果模型相比训练数据来说过于复杂,那就很有可能把训练数据本身的一些特点当作整个样本空间的特点,从而使得在训练数据上有很小的经验误差,但一旦面对新样本就会有很大误差,这种情况叫做过拟合(overfitting)。相对的是欠拟合(underfitting)。
欠拟合很容易避免,只要适当地增加模型复杂度(比方说增加神经网络的层数)就好。但过拟合是无法彻底避免的,只能缓解(减少模型复杂度/增加训练数据),这也是机器学习发展中的一个关键阻碍。
在现实任务中,要处理一个问题,我们往往有多种算法可以选择,即使是同一个算法也需要进行参数的选择,这就是机器学习中的模型选择(model selection)问题。既然泛化误差无法使用,而经验误差又存在着过拟合问题,不适合作为标准,那么我们应该如何进行模型选择呢?针对这个问题,后面的三个小节会给出回答。
这里先简单归纳一下,书中将模型选择问题拆解为(1)评估方法;(2)性能度量;(3)比较检验;三个子问题。可以这样理解:
评估方法:用什么数据做评估?如何获得这些数据?
性能度量:评估时如何衡量模型的好坏?有哪些评价标准?
比较检验:如何比较模型的性能?注意不是简单地比大小!在机器学习中性能比较是相当复杂的。
评估方法
调参和最终模型
调参(parameter tuning)一般先选定一个范围和变化步长,比如(0,1],步长 0.2,这样就有五个参数候选值。然后进行评估,选出最好的一个。这样选出的未必是全局最优的参数,但为了在开销和性能之间折中,只能这么做,毕竟我们无法试尽参数的所有取值。而且多个参数组合的情况是指数上升的,比方说有 3 个参数,每个参数评估 5 种取值,就需要测试多达
特别注意,训练/验证这个过程是为了让我们确定学习算法和算法的参数,确定了这些之后,我们需要再利用整个源数据集进行训练,这次训练所得的模型才是最终模型,也即提交给用户,进行测试的模型。
性能度量
性能度量(performance measure)指的是用于衡量模型泛化能力的评价标准。使用不同的性能度量往往导致不同的评判结果。比方说搭建推荐系统,两个模型中一个精度高,一个覆盖度高,如果我们想让更多的商品得到推荐可以就会选后一个模型。所以说,模型的好坏是相对的,取决于我们采用什么性能度量,而采用什么性能度量则应取决于我们的任务需求。
错误率和精度
精度(Accuracy):分类正确的样本占总样本的比例。
精度的局限性:当样本分布不合理时,精度不具备参考价值;eg:由于健康人>>病人,所以,将所有人判定为健康人,仍有较高的精度。
查准率,查全率,F1
假设我们正常处理一个二分类问题,按照模型预测值和真实值可以把测试样本划分为四种情形**:真正例(true positive),假正例(false positive),真反例(true negative),假反例(false negative)**。可以把结果表示为下图这个矩阵——混淆矩阵(confusion matrix)。
真实情况 | 预测结果 | |
---|---|---|
正例 | 反例 | |
正例 | TP(真正例) | FN(假反例) |
反例 | FP(假正例) | TN(真反例) |
查准率,又称准确率(precision),分类正确的正样本数占分类器判定为正样本的样本个数的比例。用于衡量模型避免错误的能力,分母是模型预测的正例数目。
查全率,又称召回率(recall),分类正确的正样本数占真正的正样本个数的比例。用于衡量模型避免缺漏的能力,分母是测试样本真正包含的正例数目。
一般来说,这两者是矛盾的,提高其中一者则另一者必然会有所降低。
F1,是查准率和查全率的调和平均,用于综合考虑这两个性能度量。
有时候我们对查准率,查全率的需求是不同的。比方说广告推荐,要尽量避免打扰用户,因此查准率更重要;而逃犯检索,因为漏检的危害很大,所以查全率更重要。这时就需要使用
其中
在排序问题中,通常没有一个确定的阈值把得到的结果直接判定为正样本或负样本,而是采用
书中还介绍了如何对多次训练/测试产生的多个混淆矩阵进行评估,包括宏方法(先分别计算性能度量,再计算均值)和微方法(先对混淆矩阵各元素计算均值,再基于均值计算性能度量)两种途径。
P-R 曲线的比较:若一个学习器曲线被另一个学习器曲线完全“包住”,则认为后者更优;如果出现交叉,可通过比较平衡点(查准率=查全率),大者更优。
P-R 曲线的绘制:对于一个排序模型来说,其 P-R 曲线的一个点代表着,在某一阈值下,模型将大于该阈值的结果判定为正样本,小于该阈值的结果判定为负样本,此时返回结果对应查全率和查准率;整条 P-R 曲线是通过将阈值从高到低移动而生成的。
ROC 与 AUC
很多时候,使用模型对测试样本进行预测得到的是一个实值或者概率(比如神经网络),需要进一步设置阈值(threshold),然后把预测值和阈值进行比较才能获得最终预测的标记。
我们可以按照预测值对所有测试样本进行排序,最可能是正例的排前面,最不能是正例的排后面。这样分类时就像是在这个序列中以某个截断点(cut point)把样本分成两部分。我们需要根据任务需求来设置截断点。比如广告推荐更重视查准率,可能就会把截断点设置得更靠前。
因此!排序本身的质量很能体现出一个模型的泛化性能,ROC 曲线就是一个用来衡量排序质量的工具。
ROC,全称受试者工作特征(Receiver Operating Characteristic)。怎样画 ROC 曲线呢?先定义两个重要的计算量**:真正例率(True Positive Rate,简称 TPR)和假正例率(False Positive Rate,简称 FPR)**。
只看定义确实有点绕,为了更直观地说明这个问题,我们举一个医院诊断病人的例子。假设有 10 位疑似癌症患者,其中有 3 位很不幸确实患了癌症(P=3), 另外 7 位不是癌症患者(N=7)。医院对这 10 位疑似患者做了诊断,诊断出 3 位癌症患者,其中有 2 位确实是真正的患者(TP=2)。那么真阳性率 TPR=TP/P=2/3。对于 7 位非癌症患者来说,有一位很不幸被误诊为癌症患者(FP=1),那么假阳性率 FPR=FP/N=1/7。对于“该医院”这个分类器来说,这组分类结果就对应 ROC 曲线上的一个点(1/7,2/3)。
如何绘制 ROC 曲线:
事实上,ROC 曲线是通过不断移动分类器的“截断点”来生成曲线上的一组关键点的,通过下面的例子进一步来解释“截断点”的概念。在二值分类问题中,模型的输出一般都是预测样本为正例的概率。假设测试集中有 20 个样本,表 2.1 是模型的输出结果。样本按照预测概率从高到低排序。在输出最终的正例、负例之前,我们需要指定一个阈值,预测概率大于该阈值的样本会被判为正例,小于该阈值的样本则会被判为负例。比如,指定阈值为 0.9,那么只有第一个样本会被预测为正例,其他全部都是负例。上面所说的“截断点”指的就是区分正负预测结果的阈值。通过动态地调整截断点,从最高的得分开始(实际上是从正无穷开始,对应着 ROC 曲线的零点),逐渐调整到最低得分,每一个截断点都会对应一个 FPR 和 TPR,在 ROC 图上绘制出每个截断点对应的位置,再连接所有点就得到最终的 ROC 曲线。
就本例来说,当截断点选择为正无穷时,模型把全部样本预测为负例,那么 FP 和 TP 必然都为 0,FPR 和 TPR 也都为 0,因此曲线的第一个点的坐标就是(0,0)。当把截断点调整为 0.9 时,模型预测 1 号样本为正样本,并且该样本确实是正样本,因此,TP=1,20 个样本中,所有正例数量为 P=10,故 TPR=TP/P=1/10;这里没有预测错的正样本,即 FP=0,负样本总数 N=10,故 FPR=FP/N=0/10=0,对应 ROC 曲线上的点(0,0.1)。依次调整截断点,直到画出全部的关键点,再连接关键点即得到最终的 ROC 曲线。
其实,还有一种更直观地绘制 ROC 曲线的方法。首先,根据样本标签统计出正负样本的数量,假设正样本数量为 P,负样本数量为 N;接下来,把横轴的刻度 间隔设置为 1/N,纵轴的刻度间隔设置为 1/P;再根据模型输出的预测概率对样本进行排序(从高到低);依次遍历样本,同时从零点开始绘制 ROC 曲线,每遇到一个正样本就沿纵轴方向绘制一个刻度间隔的曲线,每遇到一个负样本就沿横轴方向绘制一个刻度间隔的曲线,直到遍历完所有样本,曲线最终停在(1,1)这个 点,整个 ROC 曲线绘制完成。
有两个值得注意的特例:
经过 (0,1) 点的曲线,这代表所有正例都在反例之前出现(否则会先出现假正例从而无法经过 (0,1) 点),这是一个理想模型,我们可以设置一个阈值,完美地分割开正例和反例。
对角线,这对应于随机猜测模型,可以理解为真正例和假正例轮换出现,即每预测对一次接下来就预测错一次,可以看作是随机猜测的结果。
若一个模型的 ROC 曲线完全包住了另一个模型的 ROC 曲线,我们就认为这个模型更优。但是如果两条曲线发生交叉,要怎么判断呢?比较合理的判据是AUC(Area Under ROC Curve),即 ROC 曲线下的面积。
补充一点,ROC 曲线上的面积等于排序损失(loss)。也即有:
Mean Average Precision(MAP)
与 recall 的概念有些类似,不过是“顺序敏感”的 recall。对于用户

Mean Reciprocal Rank(MRR)
正确检索结果值在检索结果中的排名来评估检索系统的性能。
代价敏感错误率与代价曲线
现实任务中,有时会遇到不同类型错误造成后果不同的状况。比如医生误诊,把患者诊断为健康人的影响远大于把健康人诊断为患者,因为可能因为这次误诊丧失了最佳治疗时机。为了权衡不同类型错误带来的不同损失,可以为这些错误类型赋以非均等代价(unequal cost)。
还是举二分类为类,可以根据任务的领域知识来设定一个代价矩阵(cost matrix):
真实类别 | 预测类别 | |
---|---|---|
第0类 | 第1类 | |
第0类 | 0 | cost_{01} |
第1类 | cost_{10} | 0 |
预测值与真实值相等时,自然错误代价为 0。但把第 0 类错预测为第 1 类和把第 1 类错预测为第 0 类这两种错误的代价是不同的。注意,重要的不是代价在数值上的大小,而是它们的比值。比方说
使用了非均等代价之后,我们在使用性能度量时自然也需要作出相应的改变,比方说**代价敏感(cost-sensitive)**版本的错误率:
由于 ROC 曲线不能反应使用非均等代价之后的期望总体代价,所以改用**代价曲线(cost curve)**来取替。
代价曲线图的纵轴为归一化代价(将代价映射到 [0,1] 区间),横轴为正例概率代价。画法类似于 ROC 曲线,它是将 ROC 曲线的每一个点转为图中的一条线。依次计算出 ROC 曲线每个点对应的 FPR 和 FNR,然后把点 (0,FPR) 和点 (0,FNR) 连线。最终所得的图中,所有线的下界所围成的面积就是该模型的期望总体代价。
top1 top5
top1: 预测的label取最后概率向量里面最大的那一个作为预测结果,如果预测结果中概率最大的那个分类正确,则预测正确;否则预测错误。 top5: 最后概率向量最大的前五名中,只要出现了正确概率即为预测正确;否则预测错误。
比较检验
看起来似乎有了获取测试集的评估方法和用于比较模型的性能度量之后,就能够通过不同模型在测试集上的性能表现来判断优劣了。但是!事实上,在机器学习中,模型比较并不是这样简单的比大小,而是要考虑更多。
注:指验证集,但无论是书中还是论文中,都使用测试集较多,明白两者的区别就可以了。
在模型比较中,主要有以下三个重要考虑:
- 测试集上的性能只是泛化性能的近似,未必相同;
- 测试集的选择对测试性能有很大影响,即使规模一致,但测试样例不同,结果也不同;
- 一些机器学习算法有随机性,即便算法参数相同,在同一测试集上跑多次,结果也可能不同;
那么应该如何有效地进行模型比较呢?答案是采用假设检验(hypothesis test)。基于假设检验的结果,我们可以推断出,若在测试集上观察到模型 A 优于 B,则是否 A 的泛化性能在统计意义上也优于 B,以及做这个结论的把握有多大。
本小节首先介绍最基本的二项检验和 t 检验,然后再深入介绍其他几种比较检验方法。默认以错误率作为性能度量。
几个基础概念:
- 置信度:表示有多大的把握认为假设是正确的。
- 显著度:也称“显著性水平”,表示假设出错的概率。显著度越大,假设被拒绝的可能性越大。
- 自由度:不被限制的样本数,也可以理解为能自由取值的样本数,记为
或 。
单个模型、单个数据集上的泛化性能检验
我们有多大把握相信对一个模型泛化性能的假设?
二项检验
在进行比较检验前,完成了一次模型预测,已知测试错误率为
一个泛化错误率为
这个概率符合二项分布:
又因为已知测试错误率为
使用二项检验(binomial test),假设泛化错误率
其中
在满足右式的所有
t 检验
二项检验只用于检验某一次测试的性能度量,但实际任务中我们会进行多次的训练/测试,得到多个测试错误率,比方说进行了 k 次测试,得到
定义这
注意!这里使用的是无偏估计的样本方差,分母是
假设泛化错误率
该统计量服从自由度
自由度越大,约接近于正态分布,自由度为无穷大时变为标准正态分布(
如果计算出的 t 统计量落在临界值范围 [
两个模型/算法、单个数据集上的泛化性能检验
我们有多大把握相信两个模型的泛化性能无显著差别?
交叉验证 t 检验
对两个模型 A 和 B,各使用 k 折交叉验证分别得到 k 个测试错误率,即
对于这两组 k 个测试错误率,计算两组之间的每一对的差,即
可以看到,和前面的 t 检验相比,这里的分子没有被减项,其实是省略了。因为我们假设两个模型的泛化错误率相同,实际上是假设
类似地,这个统计量服从自由度
McNemar 检验
对于一个二分类问题,如果使用留出法,我们不仅可以获得两个算法 A 和 B 各自的测试错误率,或能够获得它们分类结果的差别(都预测正确、都预测错误、一个预测正确一个预测错误),构成一张列联表(contingency table):
算法B | 算法A | |
---|---|---|
分类正确 | 分类错误 | |
分类正确 | $e_{00}$ | $e_{01}$ |
分类错误 | $e_{10}$ | $e_{11}$ |
假设两个算法的泛化性能无显著区别,则
该变量服从自由度为
注:这里
多个模型/算法、多个数据集上的泛化性能检验
我们有多大把握相信多个模型的泛化性能皆无显著差别?若有,接下来怎样做?
在一组数据集上进行多个算法的比较,情况就变得较复杂了,一种做法是使用前面的方法分开两两比较;另一种更直接的做法是使用基于算法排序的 Friedman 检验。
Friedman 检验
假设有
数据集 | 算法 A | 算法 B | 算法 C |
---|---|---|---|
D1 | 1 | 2 | 3 |
D2 | 1 | 2.5 | 2.5 |
D3 | 1 | 2 | 3 |
D4 | 1 | 2 | 3 |
平均序值 | 1 | 2.125 | 2.875 |
令
在
以上这种检验方式也称为原始 Friedman 检验,被认为过于保守,现在通常用统计量
该变量服从于自由度为
和前面的检验方式有所区别,F 检验是根据设定的显著度
但如果这个假设被拒绝了呢?这时就需要进行后续检验(post-hoc test),常用的有 Nemenyi 后续检验。
Nemenyi 后续检验
定义平均序值差别的临界值域为:
其中
Nemenyi 后续检验还可以通过 Friedman 检验图更直观地体现出来,横轴为性能度量,纵轴为算法,每个算法用一段水平线段表示,线段中心点为该算法的平均序值,线段长度为
偏差与方差
除了估计算法的泛化性能,我们往往还希望知道为什么有这样的性能?这时一个有用的工具就是偏差-方差分解(bias-variance decomposition)。
知乎上面有两个问题都有不错的答案,不妨先看看。[1] 机器学习中的 Bias(偏差),Error(误差),和 Variance(方差)有什么区别和联系? (opens new window);[2] 偏差和方差有什么区别? (opens new window)。
对学习算法的期望繁华错误率进行拆解,最终会发现能拆解为三个项(需要推导):
依次对应于方差(variance)、偏差(bias)、噪声(noise):
这三者的含义是这样的:
方差:使用同规模的不同训练集进行训练时带来的性能变化,刻画数据扰动带来的影响;
偏差:学习算法的期望预测与真实结果的偏离程度,刻画算法本身的拟合能力;
噪声:当前任务上任何算法所能达到的期望泛化误差的下界(即不可能有算法取得更小的误差),刻画问题本身的难度;
也即是说,泛化性能是有学习算法的拟合能力,数据的充分性以及问题本身的难度共同决定的。给定一个任务,噪声是固定的,我们需要做得就是尽量降低偏差和方差。
但是这两者其实是有冲突的,这称为偏差-方差窘境(bias-variance dilemma)。给定一个任务,我们可以控制算法的训练程度(如决策树的层数)。在训练程度较低时,拟合能力较差,因此训练数据的扰动不会让性能有显著变化,此时偏差主导泛化错误率;在训练程度较高时,拟合能力很强,以至于训练数据自身的一些特性都会被拟合,从而产生过拟合问题,训练数据的轻微扰动都会令模型产生很大的变化,此时方差主导泛化错误率。
注意,将泛化性能完美地分解为方差、偏差、噪声这三项仅在基于均方误差的回归任务中得以推导出,分类任务由于损失函数的跳变性导致难以从理论上推导出分解形式,但已经有很多方法可以通过实验进行估计了。
References
《西瓜书-周志华》
familyld/Machine_Learning: 周志华《机器学习》阅读笔记 (github.com) (opens new window)
《百面机器学习》
《统计学习方法-李航》
目标检测(Object Detection)中性能衡量指标 mean Average Precision(mAP)的含义与计算_咚咚锵的博客-CSDN 博客 (opens new window)
https://blog.csdn.net/qq_40006058/article/details/89432773