正如我们在上一节讨论的,仅依赖一次训练-测试集划分有时可能会给出过于乐观或悲观的性能估计,这仅仅是因为数据划分的偶然性。如果您的测试集碰巧包含了异常容易或困难的例子,您的评估指标可能无法准确反映模型在不同未见数据上的表现。为了获得对模型性能更可靠的估计,可以采用一种方法:多次重复数据划分和测试过程,使用不同的子集进行测试并取平均结果。这就是**交叉验证(CV)**的主要思想。交叉验证通过系统地使用数据的不同部分进行测试和训练,提供了更可靠的模型性能衡量标准。它有助于平滑因单次训练-测试集划分可能产生的差异。基本原理:多次划分,结果取平均想象一下您有一个数据集。与其只将其分成两部分(训练集和测试集),您可以将其分成几个相等的部分,通常称为“折叠(folds)”。假设您将其分成5个折叠(这是一个常见的选择)。这个过程通常是这样进行的:折叠1作为测试集: 使用折叠2、3、4和5训练模型。然后,使用折叠1作为测试集评估训练好的模型。记录性能指标(例如准确率或MSE)。折叠2作为测试集: 丢弃之前的模型。使用折叠1、3、4和5从头开始训练一个新模型。使用折叠2作为测试集评估此模型。记录性能。折叠3作为测试集: 重复此过程,使用折叠1、2、4和5进行训练,并在折叠3上进行测试。记录性能。继续...: 重复此操作,直到每个折叠都恰好作为测试集使用过一次。取平均值: 计算每一步记录的性能指标的平均值。这个平均分数被认为是比单次训练-测试集划分所获得的分数,更能可靠地估计模型在未见数据上的表现。下图说明了使用5个折叠的此过程:digraph G {rankdir=LR; node [shape=box, style=filled, fontname="sans-serif", fontsize=10]; Fold1 [label="折叠 1", fillcolor="#ffc9c9"]; Fold2 [label="折叠 2", fillcolor="#a5d8ff"]; Fold3 [label="折叠 3", fillcolor="#a5d8ff"]; Fold4 [label="折叠 4", fillcolor="#a5d8ff"]; Fold5 [label="折叠 5", fillcolor="#a5d8ff"]; Iter1 [label="迭代 1:折叠 1 = 测试集", shape=ellipse, fillcolor="#fff3bf"]; Iter2 [label="迭代 2:折叠 2 = 测试集", shape=ellipse, fillcolor="#fff3bf"]; Iter3 [label="迭代 3:折叠 3 = 测试集", shape=ellipse, fillcolor="#fff3bf"]; Iter4 [label="迭代 4:折叠 4 = 测试集", shape=ellipse, fillcolor="#fff3bf"]; Iter5 [label="迭代 5:折叠 5 = 测试集", shape=ellipse, fillcolor="#fff3bf"]; Fold1 -> Iter1; Fold2 -> Iter2; Fold3 -> Iter3; Fold4 -> Iter4; Fold5 -> Iter5; } 5折交叉验证视图。数据集被分成5个折叠。在每次迭代中,一个不同的折叠用作测试集(红色),而其余折叠用于训练(绿色)。性能在所有迭代中取平均值。为什么这有帮助?通过在数据的多个独立子集上测试模型,交叉验证大大降低了评估结果因某次特别“幸运”或“不幸”的划分而出现偏差的可能性。每个数据点都用于训练和测试(尽管从不在同一次迭代中),从而提供了更全面的评估。由此产生的平均性能得分通常更能稳定可靠地表明您的模型对以前未遇到的新数据的泛化能力。这是对交叉验证的初步介绍。有多种实现方式(例如K折交叉验证、分层K折交叉验证等),它们涉及到折叠如何创建和使用的具体细节。这些方法对更细致的模型评估和比较十分有用,在您深入学习机器学习时,会经常看到它们。目前,需要记住的要点是这个原理:在数据的多个不同子集上进行评估,以获得更可靠的性能估计。