[Day 24] 机器学习 - 不能忽视的过拟合与欠拟合

今日学习目标

  • 如何选择最佳的模型?
  • 深入理解度拟合与欠拟合
    • Bias-Variance Tradeoff
  • 如何避免过拟合与欠拟合?

前言

在机器学习中大家可能最常见的问题是,当训练好了模型并在测试资料也获得不错的成绩。於是很开心的落地并部署到真实场域中,殊不知预测出来的结果远远不如预期。我想这个痛点大家应该都经历过,尤其是机器学习的新手。这种情况就是所谓的过度拟合,它是一个在机器学习领域中非常棘手的的问题。当你的模型过度的拟合训练集,这意味着你的模型过於复杂的去记住所有现有的数据点,进而导致模型的泛化能力不佳,这不是我们期望的。所谓的模型泛化能力是指,当我利用训练集训练一个模型後再拿另一组模型没看过的资料进行预测,最终的预测结果如果在没看过的资料中依然保持不错的表现我们就可以说此模型泛化能力强。今天我们将来详细探讨何谓过度拟合,以及该如何去解决它使得模型处於一个适当的状态。

如何选择最佳的模型?

通常我们希望预测出来的结果要与实际的数值越接近越好,也就是在模型训练的过程中我们要想办法最小化误差使得模型的误差越小越好。那麽我们该如何评估训练出来的模型好坏呢?以下图为例,假设我们要训练一个二元分类器。最简单的方法是找出一条线够将这两个类别完整地分开,然而这一条切割的线要长得怎样才是好的模型呢?从下图我们可以发现红色虚线的模型完整的拟合於训练资料,而红色实线的模型相对的比较没有那麽严厉,在两个类别间适当的找出一条平滑的曲线来区隔两类的资料。

https://ithelp.ithome.com.tw/upload/images/20211006/20107247FVNgKBq3pj.png

接着我们拿测试资料进行模型预测,可以发现由於红色虚线的模型已经完整记住了训练集的趋势,因此在新的没看过的资料表现就没有那麽好了。尤其是在两类别分隔线附近的资料最能看出端倪。於是我们可以很确定红色虚线的模型已经过度拟合训练资料了。另外红色实现的模型虽然在训练集中有几笔会预测错误,但是它再测试集资料中一样保持稳定的预测能力。

https://ithelp.ithome.com.tw/upload/images/20211006/20107247yRear16gsU.png

从上述的例子我们可以得知,在训练模型时并非训练集的误差越小越好。我们必须同时拿测试集验证模型的预测能力,目标是训练集与测试集的平均误差要越近越好。

一个适当的机器学习工作流程包括:

  • 切割训练集与测试集
  • 资料视觉化与前处理
  • 寻找适合的模型
  • 调整模型超参数
  • 使用适当的指标评估模型
  • 交叉验证模型

Overfitting vs. Underfitting

过度拟合的反义就是欠拟合,从字面上可以得知模型预测能力是不好的。当模型太简单时会发生欠拟合,或是加入太多的 L1/L2 正则化限制模型预测能力,使模型在从数据集中学习时变得不灵活。一个过於简单的模型在预测中往往具有较小的方差(variance)而导致偏差(bias)就会变大。相反的过於复杂的模型会有较的变异进而导致方差大,同时偏差会变小。偏差和方差都是机器学习中的预测误差的方式。在一般情况下我们可以减少偏差所引起的误差,但可能会导致增加方差引起的误差,反之亦然。

https://ithelp.ithome.com.tw/upload/images/20211006/2010724718DYuY9UnI.png

这里我们就要来思考机器学习模型中的 error 从何而来?模型中的 error 是判断一个模型的好坏依据,但其实我们可以将 error 拆分成两大部分。分别有 Bias 与 Variance 两个部分。以实际例子来说,假设输出 y 是输入 x 真正的答案,而 ŷ 则是透过模型 f(x) 训练出来的预测值,我们希望预测的结果要与真实答案越接近越好,当 ŷ≠y 时就会产生 error (误差)。

Bias-Variance Tradeoff

方差与偏差之间存在着一些关系,我们必须从中找到一个适当的平衡点。因此我们希望透过权衡 bias error 跟 variance error 来使得总误差达到最小。我们常会以打靶例子解释方差与偏差之间的关联性。假设我们发射十次,我们説一个人的打靶技术很精准。其中的就表示这十个把面上的点彼此间距离都相当近,也就是我的方差非常低(low variance)。另外所谓的就表示这十个点都离准心很近,也就是我们的偏差非常低(low bias)。

https://ithelp.ithome.com.tw/upload/images/20211006/20107247opxBwn5yBj.png

  • Underfitting: 过於简单的模型使得预测结果弹性不高,训练集与测试集表现都不好。low variance (high bias)。
  • Overfitting: 过於复杂的模型使得训练集完整的被拟合,因此训练集表现极好,但测试集表现不佳。high variance (low bias)。

Error from Bias

偏差(bias)就是模型的预测与真实值之间的差异。一般我们训练模型是期望预测的值要与实际的答案要越接近越好。然而当一个简单的线性模型可能无法完整地拟合到一个复杂非线性的资料集。因此如下图所示,当一个模型训练结果偏差过大我们可以得知该模型过於简单。无论搜集再多的资料,线性的模型永远无法拟合非线性的曲线。因为比较简单的模型,他受到不同的资料的影响是比较小的。

https://ithelp.ithome.com.tw/upload/images/20211006/201072471RdwJEJezm.png

  • 简单的模型有大的 bias,小的 variance。
  • Error 来自於 bias 很大,称为欠拟合。

Error from Variance

方差(variance)是指你的模型对於资料集的敏感程度。一个过於复杂的模型会导致输出的变异性非常大。模型死背所有训练集中的数据点会导致一个问题发生。当你的训练资料有需多的随机误差或是离群值时,我们又把这些异常值全部拟合进模型里面,导致学出来的模型过於复杂同时降低泛化能力,对於未知的资料预测的能力就会很差,同时造就了很高的 variance error。因此这样的结果我们称为过度拟合。

https://ithelp.ithome.com.tw/upload/images/20211006/20107247vZ3lS4xPK3.png

  • 较复杂的模型有小的 bias,大的 variance。
  • Error 来自於 variance 很大,称为过度拟合。

如何避免欠拟合?

通常 bias 大而导致模型过於简单,而无法拟合训练资料。我们可以试着增加输入的特徵,并做一些特徵工程让模型观察多点线索。或是调整模型的演算法,使模型更复杂。例如使用项次更高的多项式模型,或是 tree-based 模型中适当的增加树的深度......等。这里更值得一提的是,当模型欠拟合时搜集再多的训练资料是没有用的。因为简单的模型比较不会受资料的影响,所以 variance 相对的会比较低而 bias 大,也就是输出的变化性不大。从这里我们可以得知简单的模型受到不同的输入资料受到的影响是比较小的。因为模型选得不好,再怎麽训练他的 bias 还是一样大。

  • 增加输入特徵或特徵工程
  • 提高模型复杂度

如何避免过度拟合?

当模型过於复杂过度拟合发生的机率相对提高,我们可以从训练集与测试集观察,很容易地检测模型是否过度拟合。但是我们应该如何避免模型太过於复杂,而导致过度拟合发生呢?通常我们会诊断这些错误的来源,这些错误来自於两种,分别为有 bias 与 variance。如果我们能够诊断出这些错误的来源,我们就能挑出适当的方法来改善模型。以下几点或许能够帮助你进行建模:

  • 搜集更多训练资料
    • 增加讯练集的资料量是有效控制 variance 的方法,并且不会增加 bias。
  • 模型添加 Regularization
    • 在损失函数中增加一些限制式,降低模型复杂。
  • 交叉验证
    • 从训练集中切出验证集,并挑出好的模型。而不是从测试集中求最小 error。
  • Early Stopping
    • 设定当模型连续几带都无法改善 error,就立即终止训练。
  • Ensembling
    • 透过训练多个模型,并取得每个模型预测并平均作为最终输出。

Reference

本系列教学内容及范例程序都可以从我的 GitHub 取得!


<<:  Day21 探讨setting(3)

>>:  ETA Screen (1)

【没钱买ps,PyQt自己写】Day 3 - 用 pyinstaller 将 python 程序打包,把每天的成果分享给你的亲朋好友

看完这篇文章你会得到的成果图 因为 PyQt5 要学的东西太多, 我们先来学打包 python 好了...

[Day-9] R语言 - K - means ++ 实作 ( K - means ++ in R.Studio)

您的订阅是我制作影片的动力 订阅点这里~ 影片程序码 library(naniar) data(ir...

Day 9 任务的形式

今天想发ARM的文章时,居然一直遇到这个画面: 虽然不确定是不是被攻击了,但後来还好可以连上主页了,...

Day 23 : Tkinter-利用Python建立GUI(基本操作及布局篇)

在进入Tkinter之前,先来讲讲GUI到底是甚麽。 GUI GUI其实就是图形使用者介面(Grap...

[C 语言笔记--Day15] 如何清空终端机

// clear.c #include <stdio.h> int main() { p...