1 、经验误差与过拟合
我们把学习器的实际输出与样本的真实输出之间的差异称为"误差"
学习器在训练集上的误差称为"训练误差" 或经验误差
在新样本上的误差称为"泛化误差"
显然,我们希望得到泛化误差小的学习器,然而,我们事先并不知道新样本什么样,实际能做的就是努力使经验误差最小化。
我们实际希望的,是在新样本上能表现的很好的学习器,为了达到这个目的,应该从训练样本中尽可能学出适用于所有潜在样本的"普遍规律",这样才能在遇到新样本时做出正确的判别
然而,当学习器把训练样本学的"太好"了的时候,很可能已经把训练样本自身的一些特点当作了所有潜在样本都会具有的一般性质,这样会导致泛化性能下降,这种现象在机器学习中称为"过拟合"(overfitting)
下图给出了关于过拟合和欠拟合的一个便于直观理解的类比
有多种因素可能导致过拟合,其中最常见的情况是由于学习能力过于强大,以至于把训练样本所包含的不太一般的特性都学到了。
而欠拟合则通常是由于学习能力低下造成的,欠拟合比较容易克服,例如在决策树学习中扩展分支、在神经网络学习中增加训练轮数等。
过拟合则很麻烦,过拟合是机器学习面临的关键障碍,各类学习算法都必然带有一些针对过拟合的措施;
然而必须认识到,过拟合是无法彻底避免的,只能缓解
不同的学习方法会给出不同的模型
在现实任务中,我们往往有多种学习算法可供选择,甚至对同一个学习算法,当使用不同的参数配置时,也会产生不同的模型。
那么,我们该选用哪一个学习算法、使用哪一种参数配置呢?
这就是机器学习中的"模型选择"问题
理想的解决方案当然是对候选模型的泛化误差进行评估,然后选择泛化误差最小的那个模型。
然而如上面所讨论,我们无法直接获得泛化误差,而训练误差又由于过拟合现象的存在而不适合作为标准,那么在现实中如何进行模型评估与选择呢?
2、评估方法
通常,我们可通过实验测试来对学习器的泛化误差进行评估并进而做出选择。
为此,需使用一个"测试集"(testing set)来测试学习器对新样本的判别能力,然后以测试集上的"测试误差"(testing error)作为泛化误差的近似。
通常我们假设测试样本也是从样本真实分布中独立同分布采样而得。但需注意的是,测试集应该尽可能的与训练集互斥,即测试样本尽量不在训练集中出现、未在训练过程中使用过。
如果,测试样本被用作训练了,则得到的将是过于"乐观"的估计结果
可是,我们只有一个包含m个样例的数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . , ( x m , y m ) } D=\{(x_1,y_1),(x_2,y_2),....,(x_m,y_m)\} D={ (x1,y1),(x2,y2),....,(xm,ym)},既要训练又要测试,怎样才能做到呢?
答案:是通过对D进行适当的处理,从中产生出训练集S 和测试集T。
2.1、留出法
留出法直接将数据集D划分为两个互斥的集合。其中一个集合作为训练集S,另一个作为测试集T,即
D = S ∪ T , S ∩ T = ∅ D=S∪T,S∩T=∅ D=S∪T,S∩T=∅,在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计
留出法需要注意的三个问题:
1)需注意的是,训练/测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响。例如在分类任务中至少要保持样本的类别比例相似。如果从采样的角度来看待数据集的划分过程,则保留类别比例的采样方式通常称为"分层采样"
若S、T中样本类别比例差别很大,则误差估计将由于训练/测试数据分布的差异而产生偏差。
2) 另一个需要注意的问题是,即便给定训练/测试集的样本比例后,仍存在多种划分方式对初始数据集D进行分割。
这些不同的划分将导致不同的训练/测试集,相应的,模型评估的结果也会有差别。因此,单次使用留出法得到的估计结果往往不够稳定可靠,在使用留出法时,一般要采用若干次随机划分,重复进行试验评估后取平均值作为留出法的评估结果。
3)我们希望评估的是用D训练出的模型的性能,但留出法需划分训练/测试集,这就会导致一个窘境:
若令训练集S包含绝大多数样本,则训练出的模型可能更接近于用D训练出的模型,但是由于T比较小,评估结果可能不够稳定准确
若令测试集T多包含一些样本,则训练集S和D差别更大了,被评估的模型与用D训练出的模型相比可能有较大差别,从而降低了评估结果的保真性。
这个没有完美的解决方案,常见做法是将大约2/3~4/5 的样本用于训练,剩余样本用于测试
2.2、交叉验证法
“交叉验证法”(cross validation)先将数据集D划分为k个大小相似的互斥子集,即
D = D 1 ∪ D 2 ∪ . . . . ∪ D k , D i ∩ D j = ∅ ( i ≠ j ) D=D_1∪D_2∪....∪D_k,D_i∩D_j=∅(i≠j) D=D1∪D2∪....∪Dk,Di∩Dj=∅(i=j)
1)每个子集 D i D_i Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到。
2)然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集,这样就可获得k组训练/测试集,从而可进行k次训练和测试,最终返回的是这k个测试结果的均值。
3)显然,交叉验证法评估结果的稳定性和保真性在很大程度上取决于k的取值,为强调这一点,通常把交叉验证法称为"k折交叉验证"(k-fold cross validation)
k最常用的取值是10,此时称为10折交叉验证,其他常用的k值有 5 、20
与留出法类似,将数据集D划分为k个子集同样存在多种划分方式。为了减少因样本划分方式不同而引入的差别,k折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值。
常见的有10次10折交叉验证
2.3、自助法
我们希望评估的是用D训练出的模型,但在留出法和交叉验证法中,由于保留了一部分样本用于测试,因此实际评估的模型所使用的训练集比D小,这必然会引入一些因训练样本规模不同而导致的估计偏差
有没有什么办法可以减少训练样本规模不同造成的影响,同时还能比较高效的进行实验估计呢?
自助法(bootstrapping)是一个比较好的解决方案,它直接以自助采样法为基础。
给定包含m个样本的数据集D,我们对它进行采样产生数据集 D ∗ D^* D∗
每次随机从D中挑选一个样本,将其拷贝放入 D ∗ D^* D∗,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被采到;这个过程重复执行m次后,我们就得到了包含m个样本的数据集 D ∗ D^* D∗,这就是自助采样的结果。
显然D中有一部分样本会在 D ∗ D^* D∗中多次出现,而另一部分不会出现。
可以做一个简单的估计,样本在m次采样中始终不被采到的概率是 ( 1 − 1 m ) m (1-\frac{1}{m})^m (1−m1)