零基础学习机器学习(三)模型的评估与选择的数学原理上篇

在具体了解不同的模型及其实战之前,我们还需要建立一个科学的体系去对我们的将来训练出来的模型进行量化的评价,并且这个评价要可以用数学公式表达,只有这样,才可以量化最终模型的效果,并有方向地进行优化。

经验误差和过拟合

通常我们把分类错误的样本数占样本总数的比例称为“错误率”,即如果在m个样本中有a个样本分类错误,则错误率E = a/m;相应的,1 - a/m 就是精度。

更一般的,我们把学习器的实际预测输出与样本的真实输出之间的差异称为“误差”,学习器在训练集上的误差称为“训练误差”或“经验误差”,在新样本上的误差称为“泛化误差”。

显然,我们希望得到泛化误差小的学习器,然而,我们事先并不知道新样本是什么样,实际能做的是努力使经验误差最小。我们甚至可以得到一个在训练集上误差为0的学习器,但是这种学习器在多数情况下都不好。

当学习器把训练样本学的太好的时候,很可能把训练样本自身的一些特点当作了所有潜在样本的一般性质,这样会导致泛化性能下降,这种现象在机器学习中称为“过拟合”,与之对应的是“欠拟合”。

有多种因素可能导致过拟合,其中最常见的情况是学习能力过于强大,以至于把训练样本所包含的不太一般的特性都学到了,而欠拟合则通常是由于学习能力低下导致的,欠拟合比较容易克服,比如在决策树中扩展分支,在神经网络中增加训练轮数,而过拟合则比较麻烦

在现实的任务中,我们往往有多种学习算法可以选择,甚至同一个算法使用不同的参数配置时,也会产生不同的模型,那么我们如何选择呢?

最理想的方法当然是对候选模型的泛化误差进行评估,然后选择泛化误差小的那个模型,但是就像刚才讨论的那样,我们无法直接获取泛化误差,而训练误差又因为过拟合现象的存在不可以作为标准。

那么在现实中,我们如何进行模型的评估和选择呢?

评估方法

通常,我们可以通过实验测试来对学习器的泛化误差进行评估并进而做出选择,为此,需要一个测试集来测试学习器对新样本的判别能力,然后以测试集上的“测试误差”作为泛化误差的近似,因为我们假设测试样本也是从样本真实分布中独立同分布采样得到的。

可是,我们只有一个包含m个样例的数据集D={(x1,y1),(x2,y2),,(xm,ym)}D = \{ (x_1,y_1),(x_2,y_2),\ldots,(x_m,y_m) \} ,既要训练,又要测试,怎样才能做到呢?答案是,对D进行适当的处理,从中产生出训练集S和测试集T,这里介绍几种简单的方法:

留出法

留出法是直接将数据D划分为两个互斥的集合,其中一个集合作为训练集S,一个作为测试集T。

需要注意的是,训练/测试集的划分要尽可能保持数据分布的一致,避免因为数据划分引入额外的偏差而对最终结果产生影响,从采样的角度来讲,就是训练集和测试集中正例的比例是相同的。

另外一个需要注意的问题是,即使保证了正例的比例是相同的,选择的具体的正例不同,相应的模型训练和评估结果都会有所不同。因此,单次留出法得到的估计结果往往不够稳定,在使用留出法的时候,一般采用若干次的随机划分,重复试验评估后取平均值作为留出法的评估结果。

此外,我们希望评估的是用D训练出来的模型的性能,但留出法需划分训练集/测试集,这就会导致一个窘境,若令训练集S包含绝大多数样本,则训练出的模型可能更接近于用D训练出来的模型,但由于T比较小,评估结果可能不够准确,若令S包含更多的样本,则训练集S和D的区别就更大了,被评估的模型与用D训练出来的模型相比可能有更大的差别,从而降低了评估结果的保真性,这个问题没有完美的解决方案。

交叉验证法

交叉验证法先将数据集D划分为k个大小相同的互斥子集,即D=D1D2Dk,DiDj=D = D_1 \cup D_2 \cup \ldots \cup D_k, D_i \cap D_j = \emptyset, 每个子集都尽可能保持数据分布的一致性,即从D中分布采样得到,然后每次用 k - 1 个子集的并集作为训练集,剩下的子集作为测试集,这样就可以得到k组训练/测试集,从而可进行k次训练和测试,最终返回的是k个这样测试结果的均值。

显然,交叉验证法评估结果的稳定性和保真性很大程度上取决于k的取值,为了强调这一点,通常把交叉验证法称为“k折交叉验证”(k-flod cross validation),k的取值最常见的是10。

与留出法相似,将数据集D划分为k个子集同样存在多种划分方式,为了减小因为样本划分不同而引入的差别,k折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是折p次k折交叉验证的结果的均值,例如常见的10次10折交叉验证。

这里我理解的意思应该是,每次划分为k个子集,进行k折交叉验证,进行p次

假定数据集D中包含m个样本,若令k=m,则得到了交叉验证法的一个特例:留一法(Leave-One-Out,LOO),显然,留一法不受随机样本划分方式的影响,因为m个样本只有唯一的方式划分为m个子集——每个子集包含一个样本。

LOO使用的训练集与初始数据集相比只少了一个样本,这就使得在绝大多数情况下,留一法中被评估的模型与期望评估的用D训练出的模型很相似,因此,LOO的评估结果往往被认为比较准确。然后,留一法也有缺陷,在数据集比较大的时候,训练m个模型的计算开销可能是难以忍受的。

自助法

在留出法和交叉验证法中中,由于保留了一部份样本用于测试,因此实际评估的模型所使用的训练集比D小,这必然会引入一些因为训练样本规模不同而导致的估计偏差,而留一法计算复杂度又太高,那么有没有什么办法可以减少训练样本规模不同的影响,同时还能比较高效地进行实验估计呢?

自助法是一个比较好的解决方案,它直接以自助采样法为基础,给定包含m个样本的数据集D,我们对它进行采样产生数据集 D’: 每次随机从D中挑选一个样本,将其拷贝放入 D’,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被采到;这个过程重复执行m次后,我们就得到了包含m个样本的数据集 D’,这就是自助采样的结果,显然,D中有一部份样本会在 D’ 中多次出现,而另一部份样本不出现,可以做一个估计,样本在m次采样中都不被采样到的概率是(11m)m(1-\frac{1}{m})^m,取极限得到:

limx(11m)m=1e0.368\lim\limits_{x\to\infty}(1-\frac{1}{m})^m = \frac{1}{e} \approx 0.368

这里注意,m个样本的数据集,采样m次

即通过自助采样,初始数据集D中约有 36.8% 的样本未出现在采样数据集D‘中,于是我们可以将D’用作训练集,D\D’用作测试集

自助法在数据集较小,难以有效划分训练/测试集是很有用,但是自助法产生的数据集改变了初始数据集的分布,这会引入估计偏差。在数量足够的时,留出法和交叉验证法更常用一些。

调参与最终模型

机器学习常涉及两类参数,一类是算法的参数,也叫做“超参数”,数目通常在10以内;另一类是模型的参数,数目可能很多,例如大型的深度学习模型参数甚至有上百亿个参数。

大多数学习算法都有超参数需要设定,超参数设置不同,学得的模型性能往往有显著差异,因此,在进行模型评估和选择时,除了要对适用学习算法进行选择,还要对算法参数进行设定,这就是常说的“参数调节”或者简称“调参”。

大家可能马上想到,调参和算法选择没有什么本质区别,对每种参数配置都训练出模型,然后把对应最好的模型的参数作为结果,这样的考虑基本都是正确的,但有一点需要注意,学习算法的很多参数都是在实数范围内取之的,因此对每种配置都生成一个模型是不可行的。现实中常见的做法是,对每个参数选择一个范围和变化布长,例如在[0,0.2]范围内以0.05为步长,则实际需要评估的候选参数有5个。显然,这样选定的参数往往不是最优的,但这是在计算的开销和性能之间进行折中的效果。这还是一个参数,如果有n个参数,每个参数都有5种选择,那一共有5n5^n 中组合,这将导致大量的调参工程量,以至于在不少应用任务中,参数调的好不好很影响最终模型的效果。

给定包含m个样本的数据集D,在模型评估和选择过程中由于需要留出一部份数据进行评估测试,事实上我们只是用了一部分数据训练模型,因此在模型选择完成后,学习算法和超参数都已经定了,此时应该用数据集D重新训练模型,这个模型在训练过程中使用了全部m个样本,这个模型才是我们最终提供给用户的。

也就是说,我们学习算法和超参数确定了,我们就不需要在进行验证+调参的过程了,这个时候,我们的训练集就是全部数据,验证集就是用户真实使用过程中的数据了

我们通常把模型在实际使用过程中的数据称为测试数据,为了加以区分,,模型评估和选择中用于评估测试的数据集通常称为“验证集(Validation set)”。也就是说,我们有如下几个数据集的定义:

  1. 训练集:用来训练模型的数据集合。模型通过在训练集上进行学习,调整自身的参数以最小化损失函数,从而拟合出数据中的模式和规律。例如,在图像分类任务中,模型通过大量带有标签的图像(训练集)学习不同类别图像的特征,逐渐提高对图像类别的预测准确性。

  2. 验证集: 主要用于在模型训练过程中评估模型的性能和调整超参数。作用:在训练模型时,我们不能仅仅依靠训练集上的表现来判断模型的好坏,因为模型可能会过度拟合训练数据。通过在验证集上评估模型,可以了解模型在未见过的数据上的表现,进而调整模型的结构、学习率、正则化参数等超参数,以提高模型的泛化能力。例如,在神经网络训练中,可以使用验证集来确定最佳的网络层数、神经元数量等。组成:一般从原始数据中划分出一部分,与训练集的分布尽可能相似,且通常也带有标签或目标值。

  3. 测试集: 用于最终评估模型性能的独立数据集。作用:当模型通过训练集训练并在验证集上进行调整后,使用测试集来评估模型在完全陌生数据上的表现,以衡量模型的泛化能力和实际应用价值。测试集的结果应该尽可能接近模型在实际应用中的表现。例如,一个用于语音识别的模型,在经过训练和调整后,使用测试集来评估其对新的语音样本的识别准确率。组成:同样包含一定数量的样本数据和对应的标签或目标值,且在模型训练过程中始终保持独立,不参与模型的训练和参数调整。

性能度量

衡量模型泛化能力的评价标准,就是性能度量。性能度量反映了任务需求,在对比不同模型的能力时,使用不同的性能度量往往会导致不同的评判结果:这意味着模型的好坏是相对的,什么样的模型是好的,不仅取决于算法和数据,还取决于任务需求。

在预测任务中,给定样例集D=(x1,y1),(x2,y2),,(xm,ym)D={(x_1,y_1),(x_2,y_2), \ldots, (x_m,y_m)}, 其中yiy_i 是示例xix_i 的真实标记,要评估学习器f的性能,就要把学习器的预测结果 f(x) 与真实标记 y 进行比较。

回归任务最常用的性能度量是“均方误差”(mean squared error)

E(f;D)=1mi=1m(f(xi)yi)2E(f;D) = \frac{1}{m}\sum_{i=1}^m(f(x_i) - y_i)^2

更一般的,对于数据分布D和概率密度函数p,均方误差可描述为

E(f;D)=xD(f(x)y)2p(x)dxE(f;D) = \int_{x \sim D}(f(x) - y)^2p(x)dx

错误率与精度

错误率和精度,这是分类任务中最常用的两种性能度量,既适用于二分类任务,也适用于多分类任务。错误率是分类错误的样本数占样本总数的比例,精度则是分类正确的样本数占样本总数的比例.对样例集D,分类错误率定义为

E(f;D)=1mi=1mII(f(xi)yi)II(a)={1,a=true0,a=falseE(f;D) = \frac{1}{m}\sum_{i=1}^m II(f(x_i) \ne y_i) \\ II(a) = \begin{cases} 1,a=true \\ 0,a=false \end{cases}

精度则定义

acc(f;D)=1mi=1mII(f(xi)=yi)=1E(f;D)acc(f;D) = \frac{1}{m}\sum_{i=1}^m II(f(x_i) = y_i) \\ = 1 - E(f;D)

更一般的,对于数据分布D和概率密度函数p(),错误率与精度可分别描述为:

E(f;D)=xDII(f(xi)yi)p(x)dxacc(f;D)=xDII(f(xi)=yi)p(x)dx=1E(f;D)E(f;D) = \int_{x \sim D}II(f(x_i) \ne y_i)p(x)dx \\ acc(f;D) = \int_{x \sim D}II(f(x_i) = y_i)p(x)dx = 1 - E(f;D) \\

查全率,查准率与F1

错误率和精度虽然常用,但并不能满足所有任务需求,以西瓜问题为例,假设瓜农拉来一车西瓜,我们用训练好的模型对这些西瓜进行判别,显然,错误率衡量了有多少西瓜被判别错误,但若我们关心的是“挑出来西瓜中有多少是好瓜”,或者“所有好瓜中有多少比例被挑选出来”,此时错误率和精度就没法衡量了。

对于这种二分类问题,可将样例根据其真实类别与学习器真实类别的组合划分为,真正例(true positive, TP),假正例(false positive, FP),真反例(true,negative, TN),假反例(false,negative, FN)四种情形,正反是对于预测结果的,真假反映的是预测是否正确,即真反例说,预测是反的,真实类别是也反的。

查准率P与查全率R分别定义为:

P=TPTP+FPR=TPTP+FNP = \frac{TP}{TP+FP} \\ R = \frac{TP}{TP+FN}

查全率与查准率是一对矛盾的度量,一般来说,查准率高的情况下,查全率一般比较低。

若希望选出的瓜中好瓜比例尽可能高,则可只挑选最有把握的瓜,但这样就难免会漏掠不少好瓜,使得查全率较低,通常只有在一些简单任务中,才可能使查全率和查准率都很高。

在很多情形下,我们可根据学习器的顶测结果对样例进行排序,排在前面的是学习器认为“最可能”是正例的样本,排在最后的则是学习器认为“最不可能”是正例的样本。按此顺序逐个把样本作为正例进行预测,则每次可以计算出当前的查全率、查准率,以查准率为纵轴、查全率为横轴作图,就得到「查住率-查全率曲线,简称“P-R曲线”。

将所有样本按照模型预测为正的概率降序排列,再逐个添加到集合中,在这个过程中,集合的查全率会逐渐从0到1,查准率逐渐从1到0

P-R曲线

P-R 图直观地显示出学习器在样本总体上的查全率、查准率.在进行比较时,若一个学习器的P-R曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者,例如图中学习器A的性能优于学习器C;如果两个学习器的P-R曲线发生了交叉,例如图中的A与B,则难以一般性地断言两者孰优孰劣,只能在具体的查准率或查全率条件下进行比较,然而,在很多情形下,人们往往仍希望把学习器A与B比出个高低,这时一个比较合理的判据是比较P-R 曲线下面积的大小,它在一定程度上表征了学习器在查准率和查全率上取得相对“双高”的比例.但这个值不太容易估算,因此,人们设计了一些综合考虑查准率、查全率的性能度量。

“平衡点”(Break-Bven Point,简称 BEP)就是这样一个度量,它是“查准率=查全率”时的取值,例如图中学习器C的BEP是0.64,而基于BEP 的比较,可认为学习器 A优于B。

但是BEP还是简单了一点,所以更常用的是F1度量

F1=2×P×RP+R=2×TP样例总数+TPTNF1 = \frac{2 \times P \times R}{P + R} = \frac{2 \times TP}{样例总数 + TP - TN}

在一些应用中,对查全率和查准率的重视程度不同,所以F1有一个更加一般的度量形式,FβF_{\beta}:

Fβ=(1+β2)×P×Rβ2×P+RF_\beta = \frac{(1+\beta^2) \times P \times R}{\beta^2 \times P + R}

很多的候更们有多个二分类福消矩阵。例如进行要孜训练/测试,每改解一个温消短阵,或是在多个数据集上进行训练/测试,希望估计算法的“全周性能,甚或是执行多分类任务,每两两类别的组合都对应一个混淆矩阵……。总之,我们希望在n个二分类混淆矩阵上综合考察查准率和查全率。

-种直接的做法是先在各混淆矩阵上分别计算出查准率和查全事,记为(R,Ri).(P, Ba).(Pn,Bn),再计算平均值,这样就得到“宏查准串”(macro-P)、“宏查全率”(macro-R),以及相应的“宏F1” (macro-F1):

macroP=1ni=1nPimacroR=1ni=1nRimarcoF1=2×macroP×macroRmacroP+macroRmacro-P = \frac{1}{n}\sum_{i=1}^nP_i \\ macro-R = \frac{1}{n}\sum_{i=1}^nR_i \\ marco-F1 = \frac{2 \times macro-P \times macro-R}{macro-P + macro-R}

还可以将各混淆矩阵的对应元素进行平均,得到TP、FP、TN、 FN的平均值,基于这些平均值计算出“微查准串”(micro-P)、“微查全率”(micro-R),以及相应的“微F1” (micro-F1):

microP=TPTP+FPmicroR=TPTP+FNmircoF1=2×microP×microRmicroP+microRmicro-P = \frac{\overline{TP}}{\overline{TP}+\overline{FP}} \\ micro-R = \frac{\overline{TP}}{\overline{TP}+\overline{FN}} \\ mirco-F1 = \frac{2 \times micro-P \times micro-R}{micro-P + micro-R}

ROC与AUC

很多学习器是为测试样本产生一个实值或概率预测,然后将这个预测值与一个分类阙值(threshold)进行比较,若大于阙值则分为正类,否则为反类,例如,神经网络在一般情形下是对每个测试样本预测出一个[0.0,1.0]之间的实值,然后将这个值与0.5进行比较,大于0.5则判为正例,否则为反例.这个实值或概率预测结果的好坏,直接决定了学习器的泛化能力,实际上,根据这个实值或概率预测结果,我们可将测试样本进行排序,“最可能”是正例的排在最前面,“最不可能”是正例的推在最后面,这样,分类过程就相当于在这个推序中以某个“截断点”(cnt point)将样本分为两部分,前一部分判作正例,后一部分则判作反例。

在不同的应用任务中,我们可根据任务需求来采用不同的截断点,例如若我们更重视“查准率”,则可选择排序中靠前的位置进行被断;若更重视“查全率”,则可选择靠后的位置进行截断,因此,排序本身的质量好坏,体现了综合考虑学习器在不同任务下的“期望泛化性能”的好坏,或者说,“一般情况下”泛化性能的好坏,ROC曲线则是从这个角度出发来研究学习器泛化性能的有力工具。

与P-R 曲线相似,我们根据学习器的预测结果对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次让算出两个重要量的值,分别以它们为横、纵坐标作图,就得到了“ROC曲线”。

与P-R曲线使用查准率、查全率为纵、横轴不同,ROC曲线的纵轴是“真正例率”(True Positive Rate, 简称 TPR),横轴是“假正例率”(False PositiveRate,简称 FPR),两者分别定义为:

TPR=TPTP+FNFPR=FPTN+FPTPR = \frac{TP}{TP+FN} \\ FPR = \frac{FP}{TN+FP}

TPR其实就是查全率R

显示ROC曲线的图叫做ROC图

ROC图

现实任务中通常是利用有限个测试样例来绘制ROC图,此时仅能获得有限个坐标对,无法产生图中的光滑 ROC 曲线,只能绘制所示的近似ROC 曲线.绘图过程很简单:给定m+m^+ 个正例和mm^- 个反例,根据学习器预测结果对样例进行排序,然后把分类阈值设为最大即把所有样例均预测为反例,此时真正例率和假正例率均为0,在坐标(0,0)处标记一个点然后,将分类阈值依次设为每个样例的预测值、即依次将每个草例划分为正例,设前一个标记点坐标为(x,y),当前若为真正例,则对应标记点的坐标为(x,y+1m+)(x, y + \frac{1}{m^+}),当前若是假正例,则对应标记点的坐标为(x+1m,y)(x + \frac{1}{m^-}, y)

进行等习路的比锁时,与P及图相似,若一个学习器的ROC曲线被另一个完全“包住”,则可断言后者的性能优于前者:若两个学习器的ROC曲线发生交叉,则难以一般性的断言两者孰优孰劣,此时如果一定进行有供效比较,比较合理的方式是ROC曲线下的面积,即AUC(Area Under ROC Curve)。

从定义可知,AUC可通过对ROC曲线下的面积求和得到,假定ROC曲线是由(x1,y1),(x2,y2),,(xm,ym){(x_1,y_1),(x_2,y_2), \ldots, (x_m,y_m)} 按顺序连接而成,AUC可以估算为:

AUC=12i=1m1(xi+1xi)(yi+yi+1)AUC = \frac{1}{2}\sum_{i=1}^{m-1}(x_{i+1}-x_i)\cdot(y_i + y_{i+1})

形式化地看,AUC考虑的是样本预测的排序质量,因此它与排序误差有紧密联系。给定m+m^+ 个正例和mm^- 个反例,令D+D^+DD^-分别表示正、反例集合则排序“损失”(loss)定义为

ρrank=1m+mxD+xD(II(f(x+)<f(x))+12II(f(x+)=f(x)))\rho_{rank} = \frac{1}{m^{+}m^{-}}\sum_{x \sub D^+}\sum_{x \sub D^-}(II(f(x^+) \lt f(x^-)) + \frac{1}{2}II(f(x^+) = f(x^-)))

即考虑每一对正、反例,若正例的预测值小于反例,则记一个“罚分”,若相等,则记0.5个“罚分”,容易看出,ρrank\rho_{rank} 对应的是ROC曲线之上的面积:若个正例在ROC 曲线上对应标记点的坐标为(x,y),则 x 恰是排序在其之前的反例所占的比例,即假正例率,因此有:

AUC=1ρrankAUC = 1 - \rho_{rank}

代价敏感错误率与代价曲线

在现实任务中,经常会遇到这种情况,不同类型的错误造成的后果不同,如门禁系统错误地把可通过人员拦住,会使用户体验不佳,但是如果错误地把陌生人放入,则会造成安全事故。

为权衡不同错误类型所造成的不同损失,可以为错误赋予“非均等代价”。

以二分类任务为例,我们可根据任务的领域知识设置一个代价矩阵,其中costijcost_{ij} 表示将第i类样本预测为第j类样本的代价,一般来说costii=0cost_{ii} = 0

回顾前面介绍的一些性能度量可以看出,大都隐式地假设了均等代价,例如之前计算错误率是直接计算错误次数,并没有考虑不同的错误会造成不同的后果。在非均等代价下,我们所希望的不再是简单地最小化错误次数,而是希望最小化总体代价。

若是将二分类问题中的第0类作为正类,第1类作为反类,令D+DD^+ 和 D^- 分别代表样例D的正例子集和反例子集,则代价敏感的错误率为:

E(f;D;cost)=1m(xiD+II(f(xi)yi)×cost01+xiDII(f(xi)yi)×cost10)E(f;D;cost) = \frac{1}{m}(\sum_{x_i \sub D^+}II(f(x_i) \ne y_i) \times cost_{01} + \sum_{x_i \sub D^-}II(f(x_i) \ne y_i) \times cost_{10})

在非均等代价下,ROC曲线不能直接反应出学习器的期望总体代价,而“代价曲线”则可达到该目的。代价曲线图的横轴是取值为 [0,1] 的正例概率代价

P(+)cost=p×cost01p×cost01+(1p)×cost10P(+)cost = \frac{p \times cost_{01}}{p \times cost_{01} + (1-p) \times cost_{10}}

其中p是样例为正例的概率;纵轴是取值为 [0,1] 的归一化代价

costnorm=FNR×p×cost01+FPR×(1p)×cost10p×cost01+(1p)×cost10cost_{norm} = \frac{FNR \times p \times cost_{01} + FPR \times (1-p) \times cost_{10}}{p \times cost_{01} + (1-p) \times cost_{10}}

其中FPR是假正例率,FNR = 1 - FPR 是假反例率。

代价曲线的绘制很简单,ROC曲线上每一点对应了代价平面上的一条线段,设ROC曲线上的点的坐标为(FPR,TPR),则可计算出相应的FNR,然后在代价平面上绘制一条从(0,FPR)到(1,FNR)的线段,线段下面的面积即为该条件下的期望总体代价。如此将ROC曲线上的每个点转化为代价平面上的一条线段,取所有线段的下界,围成的面积即为在所有条件下学习器的期望总体代价。