码农要术:机器学习篇:泛化挑战

June 24, 2020

先讲一个故事,著名数学物理学家弗里曼·戴森年轻的时候曾向费米请教,因为他们提出了一个新的理论计算与费米的实验测量结果的相符。费米看了一眼就给否定了,戴森很伤心,但是还是继续请教不对的原因。费米反问道:“你们在计算过程中引入了多少个任意参数?”戴森回答说四个。于是费米讲了一句日后很著名的话:“我记得我的朋友约翰·冯·诺依曼(John von Neumann)曾经说过,”With four parameters I can fit an elephant, and with five I can make him wiggle his trunk”。翻译过来就是,四个参数画大象,五个参数象鼻晃

费米想表达的意思,是说你这套理论参数太多,什么结果都可以拟合,泛化能力不好。50年后戴森回头再看,费米的结论是对的。

泛化能力,表示模型在新的、独立的测试数据上的预测能力。机器学习的基本目标是对训练集合中样例的泛化。这是因为,不管我们有多少训练数据,在测试阶段这些数据都不太可能会重复出现。所以说,泛化很重要

有意思的是,有学者用傅立叶变换把大象拟合出来了,并且发表了一篇论文:drawing an elephant with four complex parameters.有兴趣的可以点开看一下。不过这篇论文也有些投机取巧,用的是复数,说是5个参数,实际上是10个。可以看看拟合的效果:

elephant

为什么会有泛化误差?

首先,实际问题的训练数据往往是真实数据的一个抽样,很难获取一个问题的所有样本。训练和测试的数据的分布往往就会有差异,毕竟先贤莱布尼兹说过”凡物莫不相异,天地间没有两个彼此完全相同的东西”。

其次,样本中总会存在不可消除的随机误差。这个误差不能忽略,它可以指导我们如何降低泛化误差,提高模型的泛化能力。

下面将进一步探究测试误差的本质:

偏差-方差分解 (the Bias-Variance Decomposition)

我们假设模型如下, ϵ 为随机误差,符合正态分布:

$t$为真值,$y$为观测值,$\hat{y}$为模型预测值。$f(x)$为真实模型,$\hat{f}(x)$为拟合模型。

下面几个式子再推导bias-variance的时候会用到:

在使用平方误差损失(MSE)的情形下,期望预测误差为:

可以看出,MSE被分解为三部分:噪声(Noize)方差(variance), 偏差(Bias)

那么其他loss该如何分解呢?Domingos, Pedro. “A unified bias-variance decomposition.” 曾经把各种loss的分解总结,大致有两种思路。

一种是基于真实模型进行bias-variance分解。一种是认为模型有上限,基于模型上限进行计算,忽略了真实模型。两种思路对于主预测函数(main prediction)和方差(Variance)的计算方法是一致的,区别在于对偏差(Bias)和噪声(Noise)的计算。如下图所示:

image-20200701015510876

个人觉得第一种更容易理解一些。

Bias-Variance分解其实就是把参数空间中的偏差方差的概念应用到函数空间。这种迁移的思想在机器学习领域很常见,比如梯度下降(Gradient Descent)应用在参数空间,梯度提升(Gradient Boosting)则是应用到了函数空间。

首先这套理论是多次拟合(或者训练)的结果而不是一次。所以说会有多个训练集合,多个拟合函数。这些拟合函数集假设为Y。Y作为一个集合,自然也就有均值,方差,期望。通俗的解释一下Bias-Variance分解的各项内容如下:

  1. 主预测函数(main prediction)是与集合Y中函数的loss期望最低的函数。对于0-1 loss来说,主预测函数就是众数,对于L1 loss(MAE)来说就是中位数,对于L2 loss(MSE)来说就是均值。对于概率分布相关的损失函数如交叉墒等,则是几何平均。对于深度模型里常用的自定义函数,由于太多的trick就不太好解释了。
  2. 偏差(Bias)是指主预测函数与真值之间的偏差。这里是用主预测函数来代替了拟合函数集合。
  3. 方差(Variance)则指的是Y集合中的函数与主函数的抖动有多大,可以衡量稳定性。
  4. 噪声(Noise)则是指样本与真值之间的差异。噪声无法消除,但是可以通过增加数据来减少影响。

常用loss函数的分解如下:

image-20200702175103237

从偏差-方差分解的角度看如何优化模型

既然知道了泛化误差从何而来,剩下的工作就是要降低噪声(Noize)方差(variance), 偏差(Bias)

1. 噪声角度

样本收集过程中的噪声是无法避免的,如何去噪也是今年来热门的研究方向。增加样本自然是最简单的方法,但是数据多么宝贵,有时候样本难以获取,利用好现有的样本才是比较现实的方案。

去噪方法比较多,有基于概率的,识别那些可能是Nosiy Label;有半监督学习的;有反复迭代训练,根据loss判断Nosiy Label的;也有直接带着噪声学习,改变样本权重的。后续有机会汇总一下。

2. 偏差角度

偏差一般考察的就是基本功了。数据预处理,特征加工,问题的定义,模型的选择,都是决定偏差大小的因素。

其实机器学习大部分之间并没有花费在学习阶段。数据的收集、整合、清理和预处理,特征设计都需要花费大量的时间,而且往往都是迭代进行的。

当然也有比较通用的降低偏差的方法,比如Boosting,在降低偏差的同时,方差还不会剧烈的提升。而且基本上开箱即用,这么好用的方法自然是得到了大家的广泛认可和使用。

3. 方差角度

方差没有偏差的问题那么复杂,说白了就是解决稳定性的问题。

从参数方面考虑,可以采用Shrinking的思想,让参数收敛,也就是常说的”正则化”。但是正则化会让偏差变大,这里一定要注意TradeOff的技巧。

从样本方面考虑,可以采用自助抽样(Bootstrap)。自助抽样背后的思想也很简单: 左侧为重采样后模型完全独立的的方差,右侧为重采样后模型完全相同的方差。重采样的方差一般是介于这两者之间。而且常用的一些基于Bootstrap思想的方法同时也会降低偏差,如随机森林等。

深度学习中的Dropout其实也有点类似Bootstrap,只不过Dropout采样的不是样本而是参数。

4. Trade-Off

还有个重要的方法,就是Tuning,调模型。整体的思路就是在bias和variance之间找最优点。

常用的方法有交叉验证(Cross Validation),网格搜索(Grid Search),早停(Early Stopping)等。

网格搜索是寻找最佳参数的方法,本质上也在控制模型的复杂度。需要注意的是,一般讲模型复杂度,指的是假设空间的大小。跟参数量其实关系不大。所以如正则化化参数的调节,就是在调节模型复杂度。

一般来说,模型越复杂,对数据的拟合能力就越强,偏差(Bias)越小,方差(Variance)越大。但是也有例外,比如《A Modern Take on the Bias-Variance Tradeoff in Neural Networks》一文就指出,神经网络结构宽度增加时,偏差和方差都会变小。

一般情况下,调节模型的复杂度(如变量稀疏化Sparsity,树模型的剪枝等),可以让模型效果变好。示意图如下:

image-20200705235534476

这一点从PAC Learning的角度也可以证明,一般有都有如下的结论: m为样本量。一个常识是:更多的数据往往比更好的模型更有效。因为机器学习就是研究如何让数据发挥作用。

码农要术:机器学习篇:泛化挑战 - June 24, 2020 -