上一篇博客链接: 机器学习与建模中 - 判断数据模型拟合效果的三种方法
在上一篇博客中,我们谈到了使用损失函数来判断模型的拟合效果。但是拟合效果比较好的模型不一定是最好的模型,建模的最终目的是为了预测,因此预测最精准的模型才是最好的模型。
提到预测,我们引入一个新的概念,叫作“泛化能力”(泛化能力是指机器学习算法对新鲜样本的适应能力。学习的目的是学到隐含在数据对背后的规律,对具有同一规律的学习集以外的数据,经过训练的网络也能给出合适的输出。)
比如在多项式回归的例子上(下图),对于同样的训练数据,8阶多项式的损失比1阶多项式小很多,但是对于未来的预测,8阶多项式显得非常糟糕(下右图)。由于8阶多项式的模型过于关注训练数据(过拟合),因此不能很好的泛化新数据。
为了克服过拟合,能够更好的泛化,我们一般采取以下四种方法:
方法一:验证集
方法二:交叉验证
方法三:K折交叉验证的计算缩放
方法四:清洗噪点
方法一:验证集
克服过拟合问题的一般方法是使用第二个数据集,即验证集。用验证集来验证模型的泛化能力。验证集可以单独提供或者从原始数据中抽取一部分作为验证集。比如奥运会男子100米短跑数据,抽取1980年之后的数据作为验证集,1980年之前的数据用于训练模型。
在训练集上训练出 N 个模型,为了判断模型的泛化能力,我们计算他们在验证集上的损失函数,损失函数越小则泛化能力越好。下图表明,1阶多项式模型的泛化能力最好,8阶和6阶的泛化能力较差。
下图给出了 1 阶、4 阶、8 阶多项式模型的泛化能力图,可以很直观的看出来模型的好坏。
方法二:交叉验证
交叉验证与验证相差“交叉”两个字,所谓交叉验证就是把原始数据集分为大小尽可能相等的 K 块数据集,每一块数据集轮流作为验证集,剩余的 K-1 块作为训练集训练模型。在计算损失值得时候,将K个验证集上计算出的损失值的平均数作为最后的损失值。
特殊的,当 K = N 时,即把数量为 N 的原始数据集分成了 N 份,这就使得每一次的验证集都只有一条数据。K 折交叉验证的这种特殊情况称之为留一交叉验证(Leave-One-Out Cross Validation, LOOCV),LOOCV情况下的损失值一般是用平均损失函数计算。
下图给出了奥运会男子100米短跑数据在LOOCV情况下的平均损失值,图中曲线表明 3 阶多项式模型才是损失值最小的。这个结论显然与方法一中取1980年后的数据作为验证集的结论不一样,这样的分歧并不是异常的。但是两种方法一致的结论就是,高于 3 阶的模型都是不合适的。
方法三:K折交叉验证的计算缩放
留一交叉验证似乎已经是评估模型好坏的一种好方法,他几乎可以评估各种可选择的模型。然而在工作中,我们往往要考虑成本问题,对于 LOOCV 的实现,需要训练模型 N 次,这比简单的模型选择方法要多耗费约 N 倍的时间。对于一些复杂度比较高的模型,比如高阶多项式、对数函数、三角函数等,或者对于数据量比较大的模型,这显然并不可行。
解决这个难题的方法就是限制 K 的值,令 K << N ,由此可以大大缩减训练模型的次数。
经历多年的尝试,业界习惯的令 K = 10,在 10 折交叉验证中,我们用数据集中的 10% 作为验证集,剩下的 90% 作为训练集,模型的训练只循环 10 次。特别是当数据条数 N 远远大于10 的情况下,这将会是很大的一笔节省。
方法四:清洗噪点
有时候,能影响模型泛化能力的可能是某几个噪点引起的过拟合,因此只要在数据清洗的过程中,删除噪点,或者用均值代替,或者用邻近值代替即可,数据清洗的方法请点击下面链接:
文章链接:Python数据预处理 - 数据清洗 - 洗什么?怎么洗?看完就明白了