python机器学习——欠拟合与过拟合

时间:2024-03-14 16:00:50

所谓拟合,是指机器学习模型在训练的过程中,通过更新参数,使得模型不断契合可观测数据(训练集)的过程,但在这个过程中容易出现欠拟合和过拟合的情况:一开始我们的模型往往是欠拟合的,也正是因为如此才有了优化的空间,我们需要不断的调整参数使得模型能够更好的拟合训练集数据,但是优化到了一定程度就需要解决过拟合的问题了。

欠拟合和过拟合

(1)泛化能力

泛化:具体指模型在处理没有遇见过的样本时候的表现。

好的机器学习模型目标是从已知的训练数据到未知测试的数据上泛化性能良好。这让我们可以在未来对模型没有见过的数据进行预测。

泛化能力( Generalization Ability ):是指机器学习算法对新鲜样本的适应能力,即由某学习方法得到的模型对新数据的预测能力。学习的目的是学到隐含在数据对背后的规律,对具有同一规律的学习集以外的数据,经过训练的模型也能给出合适的输出,该能力称为泛化能力。泛化误差是度量这一能力的指标。

通常期望经训练样本训练的模型具有较强的泛化能力,也就是对新输入给出合理输出的能力。应当指出并非训练的次数越多越能得到正确的输入输出映射关系。

在机器学习领域中,当我们讨论一个机器学习模型学习和泛化的好坏时,我们通常使用术语:过拟合和欠拟合。过拟合和欠拟合是机器学习算法表现差的两大原因。

(2)欠拟合

欠拟合( underfitting )就是模型没有很好地捕捉到数据特征,不能够很好地拟合数据。例如下面的例子:
python机器学习——欠拟合与过拟合
左图表示 size 与 prize 关系的数据,中间的图就是出现欠拟合的模型,不能够很好地拟合数据,如果在中间的图的模型后面再加一个二次项或者x\sqrt{x},就可以很好地拟合图中的数据了,如右面的图所示。

解决方法:
① 添加其他特征项,有时候模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决。例如,“组合”是特征添加的重要手段(例如是否喜欢打游戏,和是否是年轻人可以组合,可以表示年轻游戏爱好者的特性),无论在什么场景,都可以照葫芦画瓢,总会得到意想不到的效果。

② 当我们的已知特征特别少的时候,添加多项式特征,这个在机器学习算法里面用的很普遍,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强。例如上面的图片的例子。

③ 降低正则化参数的值,正则化的目的是用来防止过拟合的,但是现在模型出现了欠拟合,则需要降低正则化参数的值。

注意:欠拟合通常不被讨论,因为给定一个评估模型表现的指标的情况下,欠拟合很容易被发现。矫正方法是继续学习并且试着更换机器学习算法(欠拟合比较容易克服,例如在决策树学习中扩展分支、在神经网络学习中增加训练轮数或者增加神经元个数和层数等)。

(3)过拟合

过拟合( overfitting ):当某个模型过度的学习训练数据中的细节和噪音,以至于模型在新的数据上表现很差,我们称过拟合发生了。即为了得到很小的训练误差使模型变得过度复杂,这意味着训练数据中的噪音或者随机波动也被模型学习了。而问题就在于这些信息不适用于新的数据,从而导致模型泛化性能的变差。

简单理解就是训练样本的输出和期望输出基本一致,但是测试样本输出和测试样本的期望输出相差却很大。通俗讲过拟合就是模型把数据学习得太彻底,以至于把噪声数据的特征也学习到了,这样就会导致在后期测试的时候不能够很好地识别数据,即模型泛化能力太差。例如下面的例子:
python机器学习——欠拟合与过拟合

上面左图表示 size 和 prize 的关系,学习到的模型曲线如右图所示,虽然在训练的时候模型可以很好地匹配数据,但是很显然过度拟合了数据的噪声,这不是一条好的 size 与 prize 的拟合曲线。

注意:
① 任何机器学习模型在训练集上的性能表现,都不能作为其对未知测试数据预测能力的评估。
② 过拟合更可能在非参数,非线性模型中发生,因为学习目标函数的过程是易变的具有弹性的。例如,决策树就是一种无参数机器学习算法,非常有弹性并且容易受过拟合训练数据的影响。这种问题可以通过对学习过后的树进行剪枝来解决,这种方法就是为了移除一些其学习到的细节。
③ 过拟合是机器学习面临的关键障碍,各类学习算法都必然带有一些针对过拟合的措施;然而必须认识到,过拟合是无法彻底避免的,我们所能做的只是“缓解”,或者说减小其风险。关于这一点,可大致这样理解:机器学习面临的问题通常是 NP 难甚至更难,而有效的学习算法必然是在多项式时间内运行完成,若可彻底避免过拟合,则通过经验误差最小化就能获得最优解,这就意味着我们构造性地证明了“ P = NP ”;因此,只要相信“ P ≠ NP ”,过拟合就不可避免。

解决方法:
① 重新清洗数据,导致过拟合的一个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据。
② 增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。
③ 采用正则化方法。正则化方法包括 L0 正则、L1 正则和 L2 正则,而正则一般是在目标函数之后加上对于的范数,但是在机器学习中一般使用 L2 正则。

注意:
L0 范数是指向量中非 0 的元素的个数;L1 范数是指向量中各个元素绝对值之和,也叫“稀疏规则算子”( Lasso regularization )。两者都可以实现稀疏性,既然 L0 可以实现稀疏,为什么不用 L0 ,而要用 L1 呢?一是因为 L0 范数很难优化求解( NP 难问题,NP-hard ,NP 是指非确定性多项式,所谓的非确定性是指,可用一定数量的运算去解决多项式时间内可解决的问题。NP 问题通俗来说是其解的正确性能够被“很容易检查”的问题,这里“很容易检查”指的是存在一个多项式检查算法),二是 L1 范数是 L0 范数的最优凸近似,而且它比 L0 范数要容易优化求解,所以大家才把目光和万千宠爱转于 L1 范数;
L2 范数是指向量各元素的平方和然后求平方根。可以使得 W 的每个元素都很小,都接近于 0 ,但与 L1 范数不同,它不会让它等于 0 ,而是接近于 0 。L1正则化损失函数如下:
python机器学习——欠拟合与过拟合
L(W)是未加正则项的损失, λ\lambda 是一个超参,控制正则化项的大小。

L2 正则项起到使得参数 w 变小加剧的效果,但是为什么可以防止过拟合呢?一个通俗的理解便是:更小的参数值 w 意味着模型的复杂度更低,对训练数据的拟合刚刚好(奥卡姆剃刀),不会过分拟合训练数据,从而使得不会过拟合,以提高模型的泛化能力。还有就是 L2 范数有助于处理 condition number 不好的情况下矩阵求逆很困难的问题(就是岭回归)。L2正则化损失函数如下:

python机器学习——欠拟合与过拟合
L(W)是未加正则项的损失, λ\lambda 是一个超参,控制正则化项的大小。

(4)机器学习中好的拟合

理想上,我们肯定想选择一个正好介于欠拟合和过拟合之间的模型。这就是我们学习的目标,但是实际上很难达到。

为了理解这个目标,我们可以观察正在学习训练数据机器学习算法的表现。我们可以把这个过程划分为分别是训练过程和测试过程。

随着时间进行,算法不断地学习,模型在训练数据和测试数据上的错误都在不断下降。但是,如果我们学习的时间过长的话,模型在训练数据上的表现将继续下降,这是因为模型已经过拟合并且学习到了训练数据中的不恰当的细节以及噪音。同时,测试数据集上的错误率开始上升,也即是模型的泛化能力在下降。

这个完美的临界点就处于测试集上的错误率开始上升时,此时模型在训练集和测试集上都有良好的表现。

(5)两个例子

对于一个监督学习模型来说,过小的特征集合使得模型过于简单,过大的特征集合使得模型过于复杂。对于特征集过小的情况,称之为欠拟合;对于特征集过大的情况,称之为过拟合。周志华老师一个关于树叶的例子如下

python机器学习——欠拟合与过拟合
对于以下三种拟合:python机器学习——欠拟合与过拟合
① 第一张图片用一次函数拟合,拟合的函数和训练集误差较大——欠拟合

② 第二张图片用二次函数拟合,拟合的函数和训练集误差较小——合适拟合

③ 第三张图片用 7 次函数拟合,拟合的函数完美的匹配训练集数据——过拟合

显然,二次函数的拟合比较恰当。

总结:

过拟合:在训练数据上表现良好,在未知数据上表现差。

欠拟合:在训练数据和未知数据上表现都很差。

(6)如何判断一个模型是欠拟合还是过拟合

首先看一下三种误差的计算方法:

python机器学习——欠拟合与过拟合
① 学习曲线(learning curves)

学习曲线就是比较jtrainj_{train}jcvj_{cv} 。如下图所示,为一般的学习曲线,蓝色的线表示训练集上的误差 jtrainj_{train}, 粉色的线表示验证集上的误差 jcvj_{cv},横轴表示训练集合的大小。

python机器学习——欠拟合与过拟合
刚开始处于 “A” 点,表示当训练数据很小时,很容易使得训练集上的误差非常小,此时处于过拟合状态。随着训练数据的增加,训练数据上的误差 jtrainj_{train} 越来越大,而验证集上的误差 jcvj_{cv} 越来越小,jtrainj_{train}jcvj_{cv} 越来越接近但始终保持 jcvj_{cv} > jtrainj_{train}

② 交叉验证(cross-validation)

这里首先解释一下 bias 和 variance 的概念。模型的 Error = Bias + Variance ,Error 反映的是整个模型的准确度,Bias 反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度,Variance 反映的是模型每一次输出结果与模型输出期望之间的误差,即模型的稳定性。

我们可以根据 jcvj_{cv}jtrainj_{train} 两个来判断是处于欠拟合还是过拟合。

python机器学习——欠拟合与过拟合
当观察到 jcvj_{cv} 很大时,可能处在图中蓝色圆圈中的两个位置,虽然观察到的现象很相似( jcvj_{cv}都很大),但这两个位置的状态是非常不同的,处理方法也完全不同。

当 cross validation error ( jcvj_{cv} ) 跟 training error( jtrainj_{train}) 差不多,且 jtrainj_{train} 较大时,即图中标出的 bias ,此时 high bias low variance,当前模型更可能存在欠拟合。

jcvj_{cv}>> Jtrain 且 Jtrain 较小时,即图中标出的 variance 时,此时 low bias high variance,当前模型更可能存在过拟合。

参考文献

[1] 吴恩达的机器学习课程
[2] 周志华. 机器学习[M]. 清华大学出版社, 北京, 2016.
[3] 范淼,李超.Python 机器学习及实践[M].清华大学出版社, 北京, 2016.