当你刚开始接触机器学习时,你会加载一个数据集并尝试模型。你可能会想,为什么我不能用所有数据来构建一个模型,并在同一个数据集上评估它呢?
这似乎很合理。更多的数据来训练模型更好,对吧?在同一数据集上评估模型并报告结果将告诉你模型的优劣,对吧?
错了。
在这篇文章中,你将发现这种推理的困难,并理解为什么在未见过的数据上测试模型很重要。
在同一数据集上训练和测试
如果你有一个数据集,比如鸢尾花数据集,那么这个数据集的最佳模型是什么?

鸢尾花
照片作者:dottieg2007,部分权利保留
最好的模型就是数据集本身。如果你取一个给定的数据实例并要求它的分类,你可以查找该实例在数据集中并每次报告正确结果。
这就是你在同一数据集上训练和测试模型时要解决的问题。
你要求模型对它“见过”的数据做出预测。数据用于创建模型。这个问题的最佳模型就是上面描述的查找模型。
描述性模型
在某些情况下,你确实希望训练一个模型并在同一数据集上对其进行评估。
你可能想简化数据集预测变量的解释。例如,你可能想要一组简单的规则或一个决策树来最好地描述你收集到的观测结果。
在这种情况下,你正在构建一个描述性模型。
这些模型可能非常有益,可以帮助你的项目或业务更好地理解属性如何与预测值相关。你可以用你拥有的领域专业知识为结果添加意义。
描述性模型的一个重要限制是,它仅限于描述其训练数据。你不知道它的预测准确性如何。
建模目标函数
考虑一个虚构的分类问题,其目标是将数据实例分类为红色或绿色。

建模目标函数
照片作者:seantoyer,部分权利保留。
对于这个问题,假设存在一个完美的模型,或者一个完美的函数,可以正确地区分来自该领域的任何数据实例是红色还是绿色。在一个特定的问题上下文中,完美的判别函数很可能在问题领域对领域专家具有深刻的意义。我们想思考这个问题并试图借鉴这种观点。我们想交付这个结果。
我们为这个问题构建预测模型的目标是最好地逼近这个完美的判别函数。
我们使用从该领域收集的样本数据来构建我们对完美判别函数的近似。它不是所有可能的数据,而是所有可能数据的一个样本或子集。如果我们拥有所有数据,那么就不需要进行预测,因为答案可以直接查找。
我们用于构建近似模型的数据包含了与理想判别函数相关的结构。数据准备的目标是最好地向建模算法展示这种结构。数据还包含与判别函数无关的内容,例如数据选择的偏差和扰动并隐藏结构的随机噪声。我们选择的模型来逼近函数必须能够应对这些障碍。
这个框架帮助我们理解描述性模型和预测性模型之间的更深层次的区别。
描述性模型与预测性模型
描述性模型只关心对观测数据中的结构进行建模。在同一数据集上训练和评估它是合理的。
预测性模型尝试解决一个更困难的问题,即从数据样本中逼近真实的判别函数。我们希望使用不挑选和建模样本中所有噪声的算法。我们确实希望选择能够泛化到观测数据之外的算法。因此,我们只能从数据样本中评估模型泛化到训练期间未见过的数据的能力。
最佳描述性模型在观测数据上是准确的。最佳预测性模型在未观测数据上是准确的。
过拟合
在训练数据上评估预测模型的缺陷在于,它无法告知你模型在新未见过的数据上泛化得有多好。
一个模型之所以被选择是因为它在训练数据集上的准确性,而不是它在未见过测试数据集上的准确性,它在新未见过测试数据集上的准确性很可能较低。原因是该模型没有很好地泛化。它已专门化为训练数据集中的结构。这被称为过拟合,而且它的隐蔽程度超乎你的想象。
例如,你可能想在模型准确性停止提高后停止训练模型。在这种情况下,会有这样一个点:训练集上的准确性会继续提高,但未见过的数据上的准确性会开始下降。
你可能会想:“所以我会训练训练数据集,并在过程中瞥一眼测试数据集”。这个想法不错,但现在测试数据集不再是未见过的数据了,因为它已经参与并影响了训练数据集。
应对过拟合
你必须在未见过的数据上测试你的模型来对抗过拟合。

应对过拟合
照片作者:Adrian Fallace Design & Photography,部分权利保留。
将数据按 66%/34% 的比例分割用于训练和测试数据集是一个不错的开始。使用交叉验证更好,而使用多次交叉验证则更好。你需要花时间来获得模型在未见过数据上准确性的最佳估计。
你可以通过降低模型的复杂度来提高其准确性。
例如,在决策树的情况下,你可以在训练后修剪树(删除叶子)。这将减少在特定训练数据集中的专门化程度,并提高在未见过数据上的泛化能力。例如,如果你使用回归,你可以在训练过程中使用正则化来约束复杂度(系数的大小)。
总结
在这篇文章中,你学习了将预测模型的开发表述为对未知理想判别函数的逼近这一重要框架。
在该框架下,你了解到仅在训练数据上评估模型是不足够的。你了解到评估预测模型泛化能力的最佳且最有意义的方法是在未见过的数据上进行评估。
这个直觉为为什么在评估预测模型时,在测试工具中使用训练/测试分割测试、交叉验证以及理想情况下多次交叉验证至关重要提供了基础。
想了解关于测试与训练数据的信息。
很棒的文章,我刚开始学习机器学习,一直想知道他们为什么要把数据分开。
问题:假设我把数据分成 80% 训练和 20% 测试(数字为 100, 20)。训练数据的均方根误差(RMSE)是使用 80 个观测值计算的。另一方面,测试数据的 RMSE 是仅使用 20 个观测值计算的。这是正确的吗?
谢谢
很高兴你觉得有帮助,Andy。
是的。训练 RMSE 是在训练数据集上计算的,测试 RMSE 是在测试数据集上计算的。测试数据集 RMSE 可以让你粗略了解该方法在新数据上的表现。
交叉验证将提供更好的想法,因为它更具鲁棒性。
一旦你找到一个看起来做得很好的模型,就用所有训练数据来训练它,并开始在生产环境中使用它来做出预测。
希望这能有所帮助。
嗨 Jason,有没有什么方法可以评估需要多少属性才能达到算法性能的巅峰?假设我们原始数据集有 30000 个实例和 300 个属性,是否有人可以使用 Weka 中的实验器来执行特征选择(降维)?
谢谢
嗨 Nikos,
这取决于具体问题。实验和反复试验可以给你一个明确的答案。
Jason,感谢这篇文章。你知道是否有“最后完成”训练模型的方法吗?一种在包含所有数据的信息的同时保持模型泛化特性的方法。我在想类似……
1. 只使用训练数据训练模型,直到测试数据的准确性开始下降。
2. 使用非常小的学习率再训练模型一个 epoch,以使用所有数据。
我试过了,但对我不起作用。想知道你是否知道更好的解决方案。
谢谢,
嗨 Will,
通常,我们使用交叉验证等来找到最适合该问题的算法和参数。
然后,我们使用所有可用数据来训练模型+参数,并开始使用它进行预测。
这有帮助吗?
很好,也非常好的机器学习文章。感谢 Jason Brownlee
不客气,Baouche。
如何确定模型是过拟合还是欠拟合?您计算 RMSE 或交叉验证……但 RMSE 的值应该是多少才能没有误差?或者说,RMSE 要达到什么程度才没有误差?……您如何确定?
对于迭代算法(如神经网络)来说更容易,因为我们可以绘制学习曲线。
https://machinelearning.org.cn/learning-curves-for-diagnosing-machine-learning-model-performance/
通过在训练集和测试集上进行一次性评估来诊断要困难得多。
当线性模型用于预测训练数据集本身时,它总是使得(实际值之和=预测值之和)。这是正常的吗?有什么原因吗?
感谢您的文章,它真的很有帮助……请问是否有一个随机分割数据集的标准做法,例如 70-30,如果是的话,这种方法叫做什么?
这是否仍可视为一种交叉验证形式?
是的,或者类似的。这被称为训练/测试分割——一种数据重采样方法。
嗨,Jason
目前正在研究分类器模型……
数据是从随机抽样方法生成的……
每次我们从机器接收新数据并将其用于运行模型时,我们都不会将其拆分为训练、验证和测试。
我们几乎每天都在用新数据训练模型。
我们的模型(使用 xgboost)…… ROC_AUC 分数和混淆矩阵没有显示出剧烈变化。
你认为这是好方法吗?请建议。
没有最好的方法。
我建议集思广益替代方法(例如,更新模型而不是从头重新拟合,什么都不做等),并比较这些方法,看看它们如何影响预测技能。
嗨,Jason,
我现在用 keras 制作分类器模型。我有 20k 图像数据,80k 用于训练,20k 用于测试。我使用验证集作为拟合模型时的验证数据;但是,我的训练和验证准确性很快就收敛了。从 0.7 可以达到 0.9,最后我的验证准确性达到 1.0,我不明白我的分类器是否过拟合了?
如果训练数据的技能持续提高,而验证数据的技能变差,则表明你的模型过拟合了。
我建议在训练期间收集损失信息并绘制学习曲线来诊断模型是否过拟合。
嗨,Jason,
假设我正在使用逻辑回归构建预测模型。我将数据分成 70-30,我的模型在验证数据上预测得很好。现在,当我将此模型应用到新数据集时,模型却未能正确预测(准确性下降)。
1) 在这种情况下,应该采取哪些步骤来提高模型在新数据集上的准确性?
2) 哪些是避免未来出现这种情况的最佳实践?
看起来你正在问一个关于如何开发稳健模型的一般性问题。
此清单包含一系列可尝试的思路。
https://machinelearning.org.cn/machine-learning-performance-improvement-cheat-sheet/
嘿 Jason,我对这种情况感到好奇。
假设你正在使用 sklearn 的 ExtraTreesClassifier 进行二元分类。你使用 20/80 的训练/测试分割,只训练 20%,预测 80%。你没有为模型指定 max_depth。你在训练集和测试集上都达到了 99% 以上的准确率。
根据定义,两种得分都不属于过拟合的范畴(我认为)。在你看来,这是否是坏事?为了让情况进一步发展,想象一下你对数据集进行了上采样,从 500,000 增加到 1,000,000,因为“1”太少了(存在严重的类别不平衡)。
对你的想法感到好奇。
听起来不错。
你好 Jason,
你对在线机器学习算法有什么看法?我不认为你写过关于它们的内容。我怀疑这些模型不太容易过拟合。与依赖批处理学习方法的传统算法不同,在线模型在每个训练实例后都会更新其参数。我怀疑这些算法更能适应新信息。
谢谢
这真的取决于数据。
我希望详细介绍在线学习,感谢您的提示!
你好 Jason,
很棒的文章!我有一个相关的问题。
在我看来,7:3 / 8:2 的训练/测试分割经验法则应该可以确保训练好的模型不会过拟合数据。
当训练集和测试集的分布不同时(协方差偏移)会是怎样的情况?
直观地说,对于鸢尾花数据集,9:1 的分割意味着模型会过拟合:它在从同一鸢尾花数据集中收集的测试集上表现太好,而在从另一个包含相同花类型的相同属性的数据集收集的测试集上表现可能不好。因为噪声,所以分布是不同的,对吧?
但是,如果两个数据集(鸢尾花数据集和其他用于测试的数据集)都足够代表总体(足够大),即使数据集不同,它们的分布也应该大致相同。那么即使是 9:1 的比例也不会意味着过拟合,对吧?
更进一步说,如果只有鸢尾花数据集足够代表总体(很大),但它在几个分布略有不同的较小数据集上表现良好,那么即使是 99:1 这样极端的训练/测试分割比例也是合理的,不是吗?
如果您有时间再次评论,我将非常感激!
你仍然可能过拟合,这真的取决于数据/项目/使用的方法等。
选择的训练/测试比例可以减少误差估计的偏差。在这方面,k 折交叉验证通常做得更好。
理想情况下,我们确实寻求样本之间相似的分布,例如,我们可以查看单变量摘要统计数据。
抱歉,不确定我是否理解你关于极端数据分割的评论。
非常感谢您的快速回复!
我明白了,是的,数据质量和方法也需要考虑。
关于极端数据分割
假设我正在构建一个预测花瓣长度的模型。如果我的训练/测试分割比例为 99:1,如果训练集和测试集来自同一数据集,则肯定会导致过拟合。
但是,如果训练集和测试集来自不同的来源(训练集来自庞大的数据集 A,测试集来自另一个数据集 B)并且
1. 使用的机器学习方法适用于预测花瓣长度
2. 测试集的质量好(异常花瓣长度很少)
3. 测试集的大小足够大(不小于例如 2000 个数据点)
3. 达到的识别准确率好(例如,3 个类别为 80%)
那么即使是 99:1 的训练/测试分割比例也足以证明我的模型是足够的,对吗?
良好的准确性是否也表明花瓣长度的分布不仅在数据集 A 和 B 中相似,而且这些数据集也代表了总体?
如果您有时间再评论一次,将不胜感激!
总的来说,我不能同意。
像这样的泛化想法在应用机器学习中是站不住脚的,每个数据集都不同,需要通过对照实验来收集数据以了解情况。
确实,用代表领域的数据来拟合模型是好的。
对过拟合问题的一个很好的解释。我没想到数据是最好的模型,但这是有道理的!当然,我们创建模型或训练机器学习算法是为了达到与我们拥有研究领域每个可能实例的每个可能标签时相当的准确性、功效或置信度。
这确实是一个令人耳目一新的观点。谢谢!
很高兴能帮到你。
非常好的文章。
你认为训练准确率 95% 而测试准确率 100% 是由过拟合引起的吗?尽管使用 SVM 在相同数据集上,测试准确率低于训练准确率,这似乎更符合逻辑。
可能是欠拟合或拟合得很好。
如果训练准确性远高于测试准确性,那才是过拟合。
嗨,Jason,
好文章。我有一些相关问题。我尝试使用梯度提升创建模型并使用 RMSE 进行评估。RMSE 值一直在下降,并且在训练、验证分割 70:30、验证分割 5:95、交叉验证 5~10 折以及多次交叉验证中值大致相同。但是,当测试到未知数据时,误差总是大 3 倍。发生什么了?
谢谢你。
一些想法
也许新数据与训练数据差异太大?
也许模型已经过拟合了训练数据?
我尝试在异常检测问题中构建一个正常数据描述模型,该模型使用正常示例。我将正常数据按 50-50 的比例分割用于训练和验证,并且我还使用异常数据进行验证。我取得了以下结果(训练损失规律性下降,然后缓慢下降并停止下降;训练精度快速增加到 100%,而验证精度低且缓慢增加)
Epoch 0/10 Accuracy: 99.175, Loss: 1.144, Val_Acc: 3.840, Val_Loss: 0.666
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 0.666
Epoch 1/10 Accuracy: 100.000, Loss: 0.193, Val_Acc: 7.831, Val_Loss: 0.564
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 11.240
Epoch 2/10 Accuracy: 100.000, Loss: 0.190, Val_Acc: 9.921, Val_Loss: 0.527
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 9.423
Epoch 3/10 Accuracy: 100.000, Loss: 0.188, Val_Acc: 10.811, Val_Loss: 0.504
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.916
Epoch 4/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 11.621, Val_Loss: 0.486
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.539
Epoch 5/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 11.971, Val_Loss: 0.471
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.112
Epoch 6/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 12.381, Val_Loss: 0.458
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.527
Epoch 7/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 12.781, Val_Loss: 0.446
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.696
Epoch 8/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 13.161, Val_Loss: 0.435
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.618
Epoch 9/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 13.751, Val_Loss: 0.425
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.640
我的模型是否过拟合?我该如何改进我的模型?
非常感谢
我在这里有一些建议
https://machinelearning.org.cn/improve-deep-learning-performance/
嗨,Jason博士,
我尝试构建一个正常数据描述模型,该模型使用训练中的正常示例进行异常检测。我将正常数据分割为 50-50 的训练和验证集,并且我还使用异常数据进行验证。我取得了以下结果(所有损失都在规律性下降;训练精度快速提高,而验证精度低且缓慢提高)
Epoch 0/10 Accuracy: 99.175, Loss: 1.144, Val_Acc: 3.840, Val_Loss: 0.666
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 0.666
Epoch 1/10 Accuracy: 100.000, Loss: 0.193, Val_Acc: 7.831, Val_Loss: 0.564
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 11.240
Epoch 2/10 Accuracy: 100.000, Loss: 0.190, Val_Acc: 9.921, Val_Loss: 0.527
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 9.423
Epoch 3/10 Accuracy: 100.000, Loss: 0.188, Val_Acc: 10.811, Val_Loss: 0.504
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.916
Epoch 4/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 11.621, Val_Loss: 0.486
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.539
Epoch 5/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 11.971, Val_Loss: 0.471
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 8.112
Epoch 6/10 Accuracy: 100.000, Loss: 0.187, Val_Acc: 12.381, Val_Loss: 0.458
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.527
Epoch 7/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 12.781, Val_Loss: 0.446
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.696
Epoch 8/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 13.161, Val_Loss: 0.435
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.618
Epoch 9/10 Accuracy: 100.000, Loss: 0.186, Val_Acc: 13.751, Val_Loss: 0.425
=============================== Val_Acc_abn: 100.000, Val_Loss_abn: 7.640
并在测试数据上得到结果
test_normal Accuracy 6.306
test_abn1 Accuracy 100.000
test_abn2 Accuracy 100.000
test_abn3 Accuracy 100.000
我的模型是否过拟合?我该如何改进我的模型?
非常感谢
您可以审阅数据的学习曲线,以查看模型是否已过拟合。
嗨 Jason
再次感谢您精彩的博客。我构建了一个模型,使用了80%的训练数据和20%的测试数据。我多次使用了k折交叉验证,并通过训练集和测试集之间的分层样本以及折内的分层样本来控制不平衡的模型。我还使用了比最优模型差1SE的模型来防止过拟合。训练模型显示准确率为72%,测试结果显示准确率为68%。所以下降了4%。关于这种准确性下降的基准,有什么建议吗?我一直在搜索。谢谢!!
干得好!
一般来说,我不推荐在使用不平衡数据集时使用准确率,也许可以尝试F1、精确率、召回率或类似的度量。
谢谢!最后我比较了每个类别的流行度和检测到的流行度,因为我正在尝试预测选举,并想看看我的模型中每个候选人的表现。不过,我对基准测试它们引入了多少方差很感兴趣,这可以通过训练和测试数据之间准确性的下降来证明。
很有意思,做得好!
我学习了模型构建的相关知识,但仍然对训练和测试数据集有疑问。我该怎么办?请提供建议。
也许这会有帮助。
https://machinelearning.org.cn/difference-test-validation-datasets/
Jason您好!一如既往的精彩!我遵循了您的建议,对高度不平衡的数据集进行了70/30的划分和交叉验证,在阈值为0.5时取得了60/90的良好PR(分类问题)。但是,我的数据集上限约为200万条记录,约140万条用于训练,60万条用于“测试”。在生产环境中,实际评分数据集将有400万条(比60万条大得多!),并且精确率从0.6下降到0.2(但召回率仍为0.9)。理想情况下,我会用更大的真实数据集进行训练,但由于可用资源,我只能训练大约140万条记录。您有什么建议可以帮助我在评分比模型训练数据大得多的数据集时保持精确率吗?
一些补充说明
-召回率为0.9仅通过对少数类进行有放回的随机过采样直到1:1实现了训练数据集。
-最终模型使用了XGBoost、250个迭代器和8的深度。
由于我只能使用比实际要评分的数据集小得多的训练/测试数据集,所以我无法采取显而易见的方法,即用更大、更真实的数据集进行训练。我将开始尝试一些集成方法:训练几个模型,然后进行热启动或平均投票。在热启动的情况下,我的第一个模型可能会被过采样以捕获真实阳性信息增益,但后续模型可能不会。或者让后续模型使用少于200个特征。总之,感谢您的阅读!
好问题,非常棘手。
也许数据集太小/与生产环境不同?或者您可能对训练集过拟合了?
我想知道您是否可以对模型与数据集大小进行敏感性分析,看看那里发生了什么。另外,调整预测阈值以更侧重于您更关心的问题——比如真的偏向它——可能会在生产环境中有所帮助。
我很想听听您的进展,Eric。
嗨
我正在处理一个不平衡的数据集。当我进行分类时,我的训练准确率为0.991667,测试准确率为1.0。
然而,我更关心F1分数和模型的平均F1分数,因为这是一个不平衡的数据集。模型的平均F1分数是1.0。
通过这些指标,我如何判断我的模型是过拟合还是欠拟合?每个类别的F1分数接近1.0是否意味着模型没有过拟合或欠拟合?
谢谢
San
我建议不要使用准确率,原因如下:
https://machinelearning.org.cn/failure-of-accuracy-for-imbalanced-class-distributions/
平均F1得分为1.0听起来很棒,只要您使用重复的分层k折交叉验证来收集分数。
当我使用f1_score作为度量标准时,如何检查我的模型是过拟合还是欠拟合?
查看损失值,并按照这里的说明操作。
https://machinelearning.org.cn/learning-curves-for-diagnosing-machine-learning-model-performance/
嗨,Jason,
有可能过拟合测试数据吗?例如,假设我比较逻辑回归与CART预测模型的性能(例如,通过AUC衡量),然后选择在测试数据上具有最高AUC的模型。这似乎没问题。但如果我将其推向极端,比较数千个预测模型的AUC性能(例如,随机森林、弹性网络、调整CART的剪枝参数等),然后选择在测试数据上具有最高AUC的模型,我不会期望同一模型在新测试数据集上表现良好。我没见过这个担忧被经常提出,所以想听听您的看法。
谢谢,
Brent
是的,这是一个例子。
https://machinelearning.org.cn/train-to-the-test-set-in-machine-learning/
还有这里
https://machinelearning.org.cn/hill-climb-the-test-set-for-machine-learning/
这就是为什么健壮的测试框架至关重要,例如重复的分层k折交叉验证,甚至可能是嵌套的。