我想提出一个论点,@discipulus 的答案并不完全正确。
标准程序是什么?
通常,设置如下所示:
- 拆分数据集(例如,训练 60%,交叉验证 20%,测试 20%)。
- [交叉验证集] 找到最佳模型(比较不同模型和/或每个模型的不同超参数)。模型选择到此步骤结束。
- [测试集] 估计模型在“现实世界”中的表现。
注意事项
- 如果您不需要比较模型,也不需要为这些模型优化超参数,则可以跳过第 2 步,并且不分配交叉验证子集(在我们的示例中为 20%)。
- 如果您不需要对现实世界中的实际性能进行估计,您可以跳过第 3 步并且不分配测试子集(在我们的示例中为 20%)。
- 不要根据测试集的性能来选择模型。让我们想象一下,在交叉验证(步骤 2)中,模型 A(带有一些特定的超参数)获得 90% 的准确率,而模型 B(带有一些特定的超参数)获得 80% 的准确率。现在,假设您很好奇并在测试集上运行了两个模型(步骤 3),结果是模型 A 获得了 80%,而模型 B 获得了 90%(与以前相反)。该怎么办?仅使用交叉验证结果来选择模型,即这里的正确答案是使用模型A(相关答案)。为什么我不能根据测试集进行选择?因为您实际上是从许多模型中选择某个模型,并且您可能很幸运地找到了恰好在测试集上表现良好的模型,因此您将不再能够信任您的测试集准确性。更详细的解释可以在这里找到。
应用于您的示例
您使用步骤 2 和步骤 3 的原因完全相同 - 选择最佳模型及其超参数组合。你可以有这样的设置:
- 创建包含 800 个数据点的训练集,保留 200 个用于交叉验证(没有测试集,因为您没有提到要评估“真实世界”性能的估计)。
- 将交叉验证数据集与每个分类器一起使用以找到最佳超参数(例如正则化器或隐藏节点的数量)假设您的结果是:
- Model1:
LogisticRegression, regularizer=0.1, 准确率80%
- Model2:
LogisticRegression, regularizer=0.01, 准确率80%
- Model3:
LogisticRegression, regularizer=0.001, 准确率81%
- Model4:
NeuralNetwork, hidden_nodes=5, 准确率71%
- Model5:
NeuralNetwork, hidden_nodes=10, 准确率82%
- Model6:
NeuralNetwork, hidden_nodes=25, 准确率76%
就是这样,NeuralNetwork是更好的模型比LogisticRegression
如果我想评估性能怎么办?您不能将82%用作“在现实世界中”的准确度估计,因为由于您选择它,它现在具有乐观偏差。如果您想估计模型的性能,则需要添加“标准程序”部分中所述的第三步。在您的设置中,它看起来像这样:
- 创建包含 600 个数据点的训练集,保留 200 个用于交叉验证,还保留 200 个用于测试。
- [与以前相同的操作,相同的结果]。
- 在 800 个数据点(训练集 + 交叉验证集)上训练具有 10 个隐藏节点的神经网络,并在 200 个数据点(测试集)上进行测试
可重复性:如何使用嵌套的 k 折交叉验证
想象一下,你重新排列你的 1000 个数据点,然后执行第 2 步,你会得到完全不同的准确度,现在最好的模型LogisticRegression是regularizer=0.01. 这是一个问题,因为仅仅通过改组数据集我们就得到了不同的结果。
如何获得稳定的准确度估计的一种方法是对步骤 2 使用 k 折交叉验证(正如您在原始帖子中所描述的那样)。但是我们也可以对第 3 步进行 k 折交叉验证,以获得更好的准确度估计。它被称为嵌套 k 折交叉验证,如下所示:
Use k-fold cross validation (for example, if k=5, then the 1000 data points are split to `trainval` dataset with 800 data points, and `test` dataset with 200 data points).
FOR EACH of the 5 800+200 (trainval+test) datapoints splits {
Take the `trainval` 800 datapoints and use k-fold cross validation (for example, if k=8, then the 800 datapoints are split to `train` dataset with 700 data points and `val` dataset with 100 data points
FOR EACH of the 4 700+100 (train+val) splits {
Train a model with some specific hyperparameters with 700 data points, then calculate accuracy with the 100 `val` set.
}
Calculate accuracy of the best model+hyperparameter pair for the 200 datapoints.
}
您应该已经训练了 3(模型+超参数对)* 5(外部交叉验证)* 4(内部 cv)= 60 个模型。
有关嵌套 k 折交叉验证的更多资源
- Weina Jin有一篇很棒的博文,其中包括更详细的描述和实现伪代码
- 嵌套的 k 折交叉验证可以像这样可视化(图片来源):

- 伪代码也可在此处和此处获得。
- 这里和这里是嵌套 k 折交叉验证的快速总结。这是一个更长的。以下是有关嵌套 k 折验证何时有用的更多信息。
关于t检验统计分析
仅这个问题就可以保证在堆栈交换上单独发布一篇文章,但这篇文章解释了为什么它可能不是最好的想法,并且建议中使用它McNemar’s test or 5×2 Cross-Validation。
然后,我们可以选择并使用配对的学生 t 检验来检查两个模型之间的平均准确度差异是否具有统计显着性,例如拒绝假设两个样本具有相同分布的原假设。[...]
问题是,配对学生 t 检验的一个关键假设已被违反。
也就是说,每个样本中的观察结果不是独立的。作为 k 折交叉验证过程的一部分,给定的观察将在训练数据集 (k-1) 次中使用。这意味着估计的技能分数是相关的,而不是独立的,反过来,测试中 t 统计量的计算以及对统计量和 p 值的任何解释都会产生误导性错误。
关于报告偏差和置信区间
它也可能不是最好的选择。
然而,研究人员似乎对交叉验证的最佳实践以及交叉验证结果的解释存在一些混淆。特别是 [...] 标准偏差、置信区间或“显着性”指示。
在本文中,我们认为,在许多实际情况下,当实验的目标是查看学习器返回的模型在特定领域的实践中表现如何时,重复交叉验证是没有用的,并且报告置信区间或显着性具有误导性。
资料来源:关于通过重复交叉验证估计模型准确性。吉特·范温克伦,亨德里克·布洛克尔。鲁汶大学计算机科学系;比利时赫弗利。