对于机器学习来讲,我们更关心是在新数据中模型对其的预测情况是否正确(对新数据是否有泛化能力);本节讲的是,对于一个算法如果只是在这个数据中训练的比较好的话,不代表在新的数据上效果比较好,所以将会介绍怎么样去 衡量模型的好坏
值得注意的是,本节是 给定了数据与超参数并且已经训练好了模型,然后再来判断模型的好坏(与超参数与数据相关)
一、模型评估
模型指标
模型的质量要由多个指标来衡量 如分类时的 模型精度、目标检测时的mAP、部署到产品时的商业指标(模型对营收的增长、模型反馈的效率(inference latency))
通常会通过模型指标对模型进行选择(通过多个指标)
例子:广告展示
用于搜索词(在看的具体网页) --> 取出相关的网页 --> 预测用户点击广告的点击率(点击率高的给用户看)【因为不知道点击率会是多少,所以弄成一个机器学习的问题,用机器学习来判断用户的点击(二分类问题)】 --> 把所有的广告通过CTR(点击率)乘上甲方给的钱来排序 。
常见关于分类的指标
准确率(Accuracy):在样本中预测正确的比例是多少【衡量分类问题最常见的作法,但是我们不关心对负类(我们不需要的类型)的准确率】。
精度(Precision):对具体类i 看预测正确了为类i 的有多少个 比上 预测的结果为类i的总数量
召回率(Recall):对预测正确的类i个数 比上 样本中类i 的数量。
F1:作为精度与召回的权衡 。
混淆矩阵是数据科学和机器学习中经常使用的用来总结分类模型预测结果的表,用n行n列的矩阵来表示,将数据集中的记录按照“真实的类别”和“预测的类别”两个标准进行汇总。以二分类任务为例,混淆矩阵的结构如下:
TP = True Postive = 真阳性; FP = False Positive = 假阳性
FN = False Negative = 假阴性; TN = True Negative = 真阴性
第一位表示模型预测的是否正确,T(True)表示预测正确,F(False)表示预测错误;
第二位表示模型的预测结果,P(Positive)表示预测为正样本,N(negative)表示预测为负样本;
TP:表示实际为正被预测为正的样本数量,
FP:表示实际为负但被预测为正的样本数量,
FN:表示实际为正但被预测为负的样本的数量,
TN:表示实际为负被预测为负的样本的数量。
另外,TP+FP表示所有被预测为正的样本数量,同理FN+TN为所有被预测为负的样本数量,TP+FN为实际为正的样本数量,FP+TN为实际为负的样本数量。
准确率
准确率是分类正确的样本占总样本个数的比例,即:
其中,n_correct为被正确分类的样本个数,n_total为总样本个数。
准确率是分类问题中最简单直观的评价指标,但存在明显的缺陷。比如如果样本中有99%的样本为正样本,那么分类器只需要一直预测为正,就可以得到99%的准确率,但其实际性能是非常低下的。也就是说,当不同类别样本的比例非常不均衡时,占比大的类别往往成为影响准确率的最主要因素。
精确率(精确度)
精确率指模型预测为正的样本中实际也为正的样本占被预测为正的样本的比例。计算公式为:
多分类任务精确率的两种方式:
- Macro Average 宏平均:是指在计算均值时使每个类别具有相同的权重,最后结果是每个类别的指标的算术平均值。
- Micro Average 微平均:是指计算多分类指标时赋予所有类别的每个样本相同的权重,将所有样本合在一起计算各个指标。
宏平均和微平均的比较:
如果每个类别的样本数量差不多,那么宏平均和微平均没有太大差异
如果每个类别的样本数量差异很大,那么注重样本量多的类时使用微平均,注重样本量少的类时使用宏平均
如果微平均大大低于宏平均,那么检查样本量多的类来确定指标表现差的原因
如果宏平均大大低于微平均,那么检查样本量少的类来确定指标表现差的原因
召回率
召回率指实际为正的样本中被预测为正的样本所占实际为正的样本的比例
召回率直观地说是分类器找到所有正样本的能力. 召回率最好的值是1,最差的值是0.
F1 score
F1 score也被叫做F-score或F-measure。F1 score可以解释为精确率和召回率的加权平均值.
F1 score的最好值为1,最差值为0. 精确率和召回率对F1 score的相对贡献是相等的。
F1 score是精确率和召回率的调和平均值,计算公式为:
- Precision体现了模型对负样本的区分能力,Precision越高,模型对负样本的区分能力越强;
- Recall体现了模型对正样本的识别能力,Recall越高,模型对正样本的识别能力越强。
- F1 score是两者的综合,F1 score越高,说明模型越稳健。
PR曲线:
评价一个模型的好坏,不能仅靠精确率或者召回率,最好构建多组精确率和召回率,绘制出模型的P-R曲线。
下面说一下P-R曲线的绘制方法。P-R曲线的横轴是召回率,纵轴是精确率。P-R曲线上的一个点代表着,在某一阈值下,模型将大于该阈值的结果判定为正样本,小于该阈值的结果判定为负样本,此时返回结果对应的召回率和精确率。整条P-R曲线是通过将阈值从高到低移动而生成的。原点附近代表当阈值最大时模型的精确率和召回率。
如果一个模型的P-R曲线被另一个模型的P-R曲线完全包住,则可断言后者的性能优于前者,例如上面的A和B优于学习器C。
如果两个模型的PR曲线相交,如A和B的性能无法直接判断,我们可以根据曲线下方的面积大小来进行比较,但更常用的是平衡点或者是F1值。
平衡点(BEP)是P=R时的取值,如果这个值较大,则说明学习器的性能较好。
而F1 = 2 * P * R /( P + R ),同样,F1值越大,我们可以认为该学习器的性能较好。
ROC
在ROC曲线中,横轴是假正例率(FPR),纵轴是真正例率(TPR)。
真正类率(True Postive Rate)TPR: TP / (TP+FN),代表分类器预测的正类中实际正实例占所有正实例的比例。
负正类率(False Postive Rate)FPR: FP / (FP+TN),代表分类器预测的正类中实际负实例占所有负实例的比例。
ROC曲线也需要相应的阈值才可以进行绘制,原理同上的PR曲线。
下图为ROC曲线示意图,因现实任务中通常利用有限个测试样例来绘制ROC图,因此应为无法产生光滑曲线,如右图所示。
绘图过程:
step1.给定m个正例子,n个反例子,根据学习器预测得分进行排序;
step2.先把分类阈值设为最大,使得所有例子均预测为反例,此时TPR和FPR均为0,在(0,0)处标记一个点;
step3.再将分类阈值依次设为每个样例的预测值,即依次将每个例子划分为正例。设前一个坐标为(x,y),若当前为真正例,对应标记点为(x,y+1/m),若当前为假正例,则标记点为(x+1/n,y),然后依次连接各点。
ROC曲线图中的四个点
第一个点:(0,1),即FPR=0, TPR=1,这意味着FN=0,并且FP=0。这是完美的分类器,它将所有的样本都正确分类。
第二个点:(1,0),即FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确答案。
第三个点:(0,0),即FPR=TPR=0,即FP=TP=0,可以发现该分类器预测所有的样本都为负样本(negative)。
第四个点:(1,1),分类器实际上预测所有的样本都为正样本。经过以上的分析,ROC曲线越接近左上角,该分类器的性能越好。
AUC
1) AUC (Area Under Curve)
被定义为ROC曲线下的面积,取值范围一般在0.5和1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。
2)AUC 的计算方法
非参数法:(两种方法实际证明是一致的)
(1)梯形法则:早期由于测试样本有限,我们得到的AUC曲线呈阶梯状。曲线上的每个点向X轴做垂线,得到若干梯形,这些梯形面积之和也就是AUC 。
(2)Mann-Whitney统计量: 统计正负样本对中,有多少个组中的正样本的概率大于负样本的概率。这种估计随着样本规模的扩大而逐渐逼近真实值。
参数法:
主要适用于二项分布的数据,即正反样本分布符合正态分布,可以通过均值和方差来计算。
3)从AUC判断分类器(预测模型)优劣的标准
AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
注:AUC值越大的分类器,正确率越高。
二、过拟合和欠拟合
虽然模型会有很好的精度,但是在实际情况中可能会有很大的问题(在数据上取得比较好的成绩与在实际应用中做的好不好,中间是有比较大的代沟的)
训练误差:模型在训练数据上看到的错误率
泛化误差:模型在新的(没见过)数据上的训练结果的误差
例子:
用过去考试的试题来预测未来的考试
在过去考试的训练误差(在历年真题上的成绩)不一定能保证你能在未来考试能取得一个理想的成绩
学生A在历年真题上取得了不错的成绩(把所有参考书中的答案记下来了),可能在模拟考试中成绩不错,但是在真正考试的时候效果可能没那么好
学生B没有记住题目但是他理解了解题思路,虽然在历年真题上的成绩没有A这么好但是在新的考试上成绩可能也跟A差不多(或者好)。
训练与泛化误差的区别
训练误差与泛化误差都很低:这是我们想要的情况
训练误差很高但泛化误差很低:这是一个很有意思的现象,可能是由bug;如果没有bug,有可能是训练的样本过难了(训练做了小学三年级的题目结果考试是小学一年级的题目)【在训练时用了大量的数据增强或在样本中加入大量的噪音的话,训练的时候误差可能会高一点,但是测试时数据相对比较干净,可能泛化误差会好一些但也不会好太多】
泛化误差很高但训练误差很低:训练的时候做的很好但是拿到新数据就不行了,这种现象叫过拟合,过多的去看了训练数据,而没有去理解后面到底发生了什么事
训练误差很高但泛化误差很高:表示模型没有理解数据没有抓住数据中的信息,这种现象叫欠拟合。
什么样的情况会导致欠拟合与过拟合?
我们可以考虑数据的复杂性(数据有多复杂)和模型的复杂性(模型有多强大),因为是用模型去拟合数据,所以它们之间的关系会比较对等
数据相对简单,应该选取相对简单的模型,就可以得到一个正常的现在
数据比较简单,但选取了复杂的模型,可能会导致overfitting
数据比较复杂,但选取了简单的模型,则模型无法拟合数据,就会导致Underfitting
数据比较复杂,选取了复杂的模型,会得到一个正常的现象
模型的复杂度(能够拟合各种各样函数的能力)
低复杂度的模型,比较难去拟合训练的数据
高复杂度的模型,能够拟合更多函数,甚至可以把整个训练样本给记住了
其实我们是不好去比较不同算法的模型复杂度的(树与神经网络的对比)
如果两个模型本质上是一个东西,则一个模型可以学习的参数要比另一个多的话,多参数的模型相对来说要复杂一些;或者,可学习参数里面可以取多少值(取±1或任意值),有值限制的模型相对会简单一些(正则化)
模型复杂度产生的影响
模型的复杂度比较小时,训练误差与泛化误差会比较高(这时叫做欠拟合);
随着模型复杂度的增加,模型的拟合能力会变得越来越强,会导致训练误差会降低,但是泛化误差不会一直降低,其过了过特定点之后会逐渐升高(泛化误差与训练误差差距较大,过拟合【记住了太多的细节,这些过多没用的细节导致在新的样本上效果比较差】)
最好的地方是泛化误差最低的点,但是就算是最好的情况,可能还是会有overfitting
数据的复杂度
数据复杂度与以下因素有关
样本的数量(样本数越多,数据就越复杂一点)
每个样本有多少个元素
数据中是否有时间或空间的结构(股票有时间的结构,图片是有空间结构的)
多样性(多样性更大,样本就更复杂一点)
当然也是很难比较两个数据集的复杂程度(图片数据集与文本数据集【像素与字符比较】),但是可以比较类似数据的复杂程度;不一样的话很多时候要靠直觉。
当数据复杂度与模型复杂度都在变化时
给定一个模型,不断增加数据的复杂度,模型会从overfitting慢慢的变成underfitting,但是会发现泛化误差在下降。
但是随着数据复杂度越高,泛化误差会逐渐平稳,因为模型无法再从这些数据中抽取有用的信息了,这时可以考虑一下换个相对复杂的模型(其泛化误差的下限会低一点)。
对于工业界来讲,
一开始数据复杂度比较小,应该先考虑简单的网络,这样会比较容易调参,而且可能效果会很好;
但是随着样本数的变大(模型部署后不断的收集数据,对数据进行处理),逐渐就会发现之间训练的模型已经跟不上数据的进步了,这时候可能就要考虑从一个简单的模型升级到一个相对复杂的模型。
数据的复杂度和模型的复杂度是要相互匹配的。
模型的选择
需要选择一个跟数据集有着合适复杂度的模型(用于降低泛化误差,同样需要考虑商业指标)
可以先选择一个模型的类,然后再选择合适的超参数【(树:有多少棵树,树有多深)||(神经网络:选择什么架构,有多少层,有多宽/隐藏层的大小,要不要加些正则项)】
总结
我们关心的是泛化误差而不是训练误差(在新的数据上模型的表现情况);
模型复杂度:模型能够去拟合各种各样函数的能力
数据复杂度:数据里面有多少信息,信息量越大,数据复杂度越大;
模型选择:需要去选择一个合适的模型去避免欠拟合和过拟合【模型复杂度过高导致的过拟合(overfitting),模型复杂度过低导致的欠拟合(underfitting)】
三、模型验证
估计泛化误差
我们最关心的是模型的泛化误差【在未知数据上模型的表现,在统计上要用很大的数据集,在实际中通常会用测试数据集(只能使用一次),在其上的误差近似泛化误差】
比如说,课程的期中考试的分数;
本来是想预测房价的,但是如果在出了房价之后再进行预测则这样毫无意义;
Kaggle上私榜(private leaderboard)
上面的操作虽然能很好的近似泛化误差,但是实际使用比较困难(数据只能使用一次);所有在实际应用中,我们会使用验证集(Validation dataset),可以被使用多次,来看模型的质量从而进行模型的选择。
验证集是训练数据集中的一块
当我们使用“测试"这个词是,通常指的是验证(在论文中说的测试数据集通常说的就是验证数据集)
常见生成验证数据集的方法
将训练样本分成两个集合,一个是训练集,一个是验证集,在训练集上训练模型,在验证集上计算误差(或其他指标),用验证集算到的误差来近似泛化误差
一般来说会选取 n% 的样本作为验证集(可以可以取50,40,30,20,10; 取决于样本足不足够,样本数多可以选择50%作为验证集,样本不够多的话,可以选择20%作为验证集)
样本不具有随机性时
有很多时候随机不一定行(随机行的时候是假设数据、每个样本之间是符合独立同分布的【样本之间是没有关系的,是随机生成的】),因为在实际生活中很多数据不是一个随机的(不符合I.I.D.)假设。
数据中有些时序的信息,如卖房的价格、股票价格【如果选验证集是随机的话,验证和训练时可能时看同一天的数据,这时可能会有误差】;这时需要保证,验证集要在训练集之后;
样本属于不同的组(groups),同一个人的图片集【如果选验证集是随机的话,同一个人的照片可能会出现在训练与验证集中,这样精度可能会低很多(重复的样本出现在测试集中)】;这时可以 在不同组之间进行分割(不同的人来分验证集)
样本不是平衡的(有些类很多,有些类很少)【如果选验证集是随机的话,类多的样本采样了比较多,类少的采样比较少,精度可能会偏高(少类的部分没有怎么学习到)】;这时可以 在取验证集时对类少的数据采样的概率高一些(或做成平衡的数据集)
具体的例子(预测房价)
随机的选择50%的样本做验证集;决策树:深度为 13 的时候测试误差往上走了(相当于我可以看清楚全局发生的事情,并进行预测,不会过拟合于一些局部的信息);线性回归:训练和验证误差都很正常;
前一半时间训练,后一半时间做验证;决策树:深度为 6 的时候测试误差往上走了(未来的房价可能会发生很大的变化,所以过拟合提前了);线性回归:在训练时很好,但在验证时就不太行了;
k折交叉验证法(数据没有那么多)
- 把一个训练集切成k块,在这k块中取出一个作为验证集中的样本,剩下的用于训练;
- 将这k个验证误差平均起来作为验证误差
- 一般可以取k=5或者10
常见的错误
在机器学习中结果非常好90%都是bug造成的【很有可能是验证集被污染了(与训练集有重叠),新手老手都很容易犯这个错误】
举个例子,
验证集中有来自于训练集的样本【代码可能没有问题,原始样本可能是重复的,这个重复的样本可能会分到训练集和验证集】
在数据融合时经常会发生,假设要去评估在imageNet上训练模型的好坏时,所有的调优都是用imageNet的,但自己用了imageNet的标签找了新的样本作为验证集,可能我们找的图片跟imageNet中的图片可能会有重叠(记得去冗余)
信息泄露:通常发生于非随机性(I.I.D.)的数据,如 在做房价预测或股票预测时,训练时看到了未来的数据了(即验证集的数据)
总结
评估模型的泛化误差的时候通过会使用测试误差来近似泛化误差;
因为测试数据只能用一次,这样太费数据了;实际上我们使用的是验证集
验证集通常是从训练集中出来的
在验证集上,可以对模型进行多次评估来进行模型的选择
验证集需要跟真实的测试数据(部署后接收的数据)要尽量相似;特别是,对于非随机性的数据时,要预测未来时,也要保证训练集和验证集要在具有过去未来的关系;
如果验证集选取的不好的话(信息泄露),这样可能会过高的评估模型的好坏。