对训练集或整个数据集执行交叉验证

机器算法验证 交叉验证
2022-03-23 05:51:35

我对如何执行交叉验证来评估统计学习模型感到有些困惑。

如果我有一个包含 500 个观察值的数据集,我是否应该将其划分为一个训练集和测试集,例如 375 个(75%)训练观察和 125 个(25%)测试观察,并对训练集执行交叉验证?还是应该对整个数据集进行交叉验证?

只要执行交叉验证的目的是获得对测试 MSE 的更稳健估计,而不是优化某些调整参数,我的理解是您应该使用整个数据集。这样做的原因是您不会获得可用于预测未见测试观察的模型,而只是对执行交叉验证的训练集的 MSE 度量。

如果我弄错了,我该如何使用交叉验证结果来预测样本外的观察结果?

有人可以为我澄清一下吗?

如果相关,我正在解决的问题是执行交叉验证以评估 R 中随机森林模型的模型性能。提前致谢!

3个回答

我应该将它分成一个训练集和测试集,例如 375 (75%) 个训练观察和 125 个 (25%) 测试观察,并对训练集执行交叉验证?

是的

还是应该对整个数据集进行交叉验证?

测试集应该独立于训练集来处理,所以如果你真的愿意,你可以为测试集做一个单独的 CV 块,并且可以提供一些有用的见解,但不是普遍的做法。如果您计划将模型应用于一组全新的“真实世界”数据,CV 可能会很有用。鉴于测试集是从与训练集相同的人群中抽取的,如果拆分正确且没有偏差,那么它可能不会像您期望的那样有用,因为它与训练集具有相似的特征。请注意,可能值得检查这个假设。

简历的目的是什么?

只要执行交叉验证的目的是获得对测试 MSE 的更稳健估计

这不是 CV 的目的,而是估计性能指标的稳健性。正如@user86895 所说,它不测量 MSE,请参阅均方误差与最小二乘误差,哪个比较数据集?供进一步阅读。CV 在数据子集上创建多个模型,并将它们应用于从该子集中保留的数据。它遍历数据集,构建新模型,直到所有模型都包含在训练子集中并且都包含在测试子集中。最终模型建立在所有训练集上,而不是任何单个 CV 轮模型,CV 的目的不是建立模型,而是评估模型性能的稳定性,即模型的通用性。

在比较数据集上的不同数据处理或分析算法时,它提供了第一个过滤器来识别提供最稳定模型的工作路径。它通过估计训练集的子集之间的性能变化程度来做到这一点。这使您可以检测过拟合风险非常高的模型并将其过滤掉。如果没有交叉验证,您将仅根据最大性能进行选择,而不考虑其稳定性。但是,当您在已部署的情况下应用模型时,其稳定性(与现实世界人口的相关性)将比精选样本子集(即您的原始实验集)的原始性能的适度差异更重要。

交叉验证实际上对于选择模型的最粗略参数至关重要,例如使用 Q2 统计量的 PCA 或 PLS 中的组件数量(这是 R2,但在保留的数据上,请参阅PCA 的每个组件的 Q² 值是多少) 来确定过拟合何时开始降低模型性能。

如果我弄错了,我该如何使用交叉验证结果来预测样本外的观察结果?

我的意思是“我如何使用 CV 结果来估计超出我的实验集的性能?”,但如果有不同的澄清,我会更新我的答案的这一部分。

CV 用作模型稳定性的第一线估计,而不是估计现实世界设置中的性能。做到这一点的唯一方法是在真实情况下测试最终模型。CV 所做的是为您提供风险分析,如果它看起来稳定,那么您可以决定是时候在实际测试中对模型进行风险分析了。如果它不稳定,那么您可能需要大大扩展您的训练集(确保重要子组和混杂因素的均匀表示,因为这些是除随机噪声之外的过度拟合的一个来源,因为所有相关的变化都需要给予相等的暴露于模型构建过程以适当加权)并构建一个新模型。

还有一个关于现实世界验证的说明,如果它有效,它并不能证明你的模型是可推广的,只能证明它在已部署在现实世界中的特定机制下有效。

只要执行交叉验证的目的是获得对测试 MSE 的更稳健估计,而不是优化某些调整参数,我的理解是您应该使用整个数据集。

正确的。

这样做的原因是您不会获得可用于预测未见测试观察的模型,而只是对执行交叉验证的训练集的 MSE 度量。

实际上,您在测试数据上获得了 MSE 的度量,而不是训练集

如果我弄错了,我该如何使用交叉验证结果来预测样本外的观察结果?

更新:

CV 作为一种评估技术提供了一个输出:评估。它不提供您可以使用的模型。

CV 作为一种调整技术提供一个输出:模型(或模型的组件,例如最佳超参数)。它不提供评估。因此,必须在独立的测试集上进行评估,这就是保留数据的原因。

在这个问题“评估统计学习模型的交叉验证”中,我认为 CV 旨在用于评估(对吗?),而不是调整。因此,您不会以任何方式使用折叠中的 10 个模型;它们不是真正的模型,它们只是评估过程的副产品。

但是,这可能无法回答您的问题。我猜你真的很想知道:所以,现在我有一个评估,但现在我得到了一些新数据并想做出预测。我用什么来做预测?换句话说,你有一个评估,但没有一个模型。答案是你必须在整个数据集上重新训练。您的 CV 评估对应的正是这个模型。

如果我有一个包含 500 个观察值的数据集,我是否应该将其划分为一个训练集和测试集,例如 375 个(75%)训练观察和 125 个(25%)测试观察,并对训练集执行交叉验证?

是的,无论情况如何,您都应该将其作为初始步骤(test_size=0.2在 中也是合理的默认值sklearn)。

还是应该对整个数据集进行交叉验证?

尽量避免它并坚持传统的指导方针,但大多数指南和书籍没有告诉你的是你可能必须这样做。
有理论,然后有实践……如果标注的数据集很小,如果没有实用的方法来增加它,训练集在很大程度上不具有代表性的风险很高,你可能不得不放弃单独的测试集。

但是,在开始使用非标准分析路径之前,您需要确保了解与它们相关的风险以及对结论的影响。最终,该决定是基于与项目相关的需求和风险的务实决定。在金融或医疗保健等受监管的领域,您需要谨慎,但如果所有结果都是将“购买”按钮涂成绿色还是蓝色,那么风险就会降低。

遵循这种非标准的分析路径,您将失去什么:

  1. 您将放弃第二轮“泛化测试”(第一轮用于模型选择/调整的训练集上的 CV)
  2. 由于无法检查模型在应用于新数据时是否稳定,您将面临过度拟合数据的风险
  3. 您将执行更多假设检验,从而导致做出错误发现的风险更高(与第 2 点相关)
  4. 您将利用更多的研究人员自由度(分叉路径的花园) - 另一个过度拟合的途径

您将获得什么:

  1. 您将获得信心,即您的模型是在更具代表性的样本上进行训练的
  2. 您将对数据集有更深入的了解,希望包括偏差、错误和所需的数据生成过程
  3. 如果有机会重做整个事情,您将更有能力推荐改进的计划

那么,在了解了上述风险和收益之后,如何决定放弃单独的测试集呢?
这是一个建议的工作流程:

1) 使用标准方法选择和调整算法后(训练 CV + 拟合整个训练集 + 测试单独的测试集),回到训练/测试拆分,对数据集进行不同的拆分几次(例如在 scikit-learn 中使用不同的random_state参数值),每次重新执行“训练 CV + 训练集拟合 + 测试”循环并观察分数。

2)如果训练CV分数和测试分数之间的差异是相对一致的 - 太好了!无需做任何其他事情。

3) 但是,如果平均训练 CV 分数和测试分数之间的差异不一致,特别是如果在这些随机数据集拆分迭代之间哪个更大的事实有所不同 - 你有一个抽样问题。
潜在的解决方案:

a)找到另一种算法,无论训练/测试拆分如何,都能很好地推广到测试集(这可能非常具有挑战性,因为您可能开始使用一个小的标记数据集)。

b) 系统地识别和消除分裂偏差(这也可能不切实际)。

c) 继续获取更多有代表性的标记数据,直到这个问题消失。

d) 宣布这是“失败的分析”并推迟/取消模型发布,因为摆脱单独的一轮泛化测试具有与之相关的高分析风险。

e)只有当所有其他方法都失败时,放弃一个单独的测试数据集(即从过程中删除单独的泛化测试步骤)并通过对整个标记数据集的交叉验证来选择模型。
在做出模型选择/调整决策时,不仅要观察平均 CV 测试分数(这是折叠平均值的平均值),还要观察个体折叠的平均测试分数的最小/最大/标准。