sklearn k-fold中k的两层含义和划分过程 学习曲线learning-curve和交叉验证cross validation中都用到k折k-fold这个k到底什么意思k 折其实有2个k第一步把总样本分成k折组。第二步一折组用于测试验证剩余k-1 折 合并用于训练。第三步每折轮流充当一次测试折组重复第二步。所以这个轮流过程重复 k 次或称k轮。先看一个例子# 5 折交叉验证 from sklearn.model_selection import KFold import numpy as np # 示例数据X包含10行每行一个样本每行2列即2个特征 X np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16], [17, 18], [19, 20] ]) y np.array([0, 1, 0, 1, 0, 0, 0, 1, 1, 1]) # 目标变量 # 初始化 KFold5 折 kf KFold(n_splits5, shuffleTrue, random_state42) # 遍历每轮 for train_index, test_index in kf.split(X): print(\n训练集索引:, train_index, 测试集索引:, test_index)训练集索引: [0 2 3 4 5 6 7 9] 测试集索引: [1 8] 训练集索引: [1 2 3 4 6 7 8 9] 测试集索引: [0 5] 训练集索引: [0 1 3 4 5 6 8 9] 测试集索引: [2 7] 训练集索引: [0 1 2 3 5 6 7 8] 测试集索引: [4 9] 训练集索引: [0 1 2 4 5 7 8 9] 测试集索引: [3 6]k的两层含义刚好对应K折交叉验证完整流程第一层单次划分规则一轮内部逻辑把全部样本**均匀**切分为k个互不重叠、总量覆盖全部样本的子集子集也称为折或组。任意一轮中选择 1 个子集 测试集剩余 k-1 个子集合并 训练集例子代码中n_splits5即k为5、总样本 10 个。划分出 5 组每组10/5 2 个样本对照上例5组的随机划分为第1折组[18] # 括号中的数字是行的索引, 下同第2折组[0, 5]第3折组[2, 7]第4折组[4, 9]第5折组[3, 6]单轮只用其中 1 组2个样本用于测试剩下 4组合并起来8个样本用于训练。合并时保持索引原来的从小到大排列因为样本的相对顺序往往代表事件发生的先后顺序。比如第2、3、4折合并后的训练集为[0, 2, 3, 4, 5, 6, 7, 9]而不是[0, 5, 2, 7, 4, 9, 3, 6]。第二层循环k轮遍历所有组合轮流让每一组都单独充当1次测试集剩下 k-1 组合并用于训练一共执行 k 次循环第 1 轮第 1 组用于测试2/3/4/5 组合并训练第 2 轮第 2 组用于测试1/3/4/5 组合并训练……第 5 轮第 5 组用于测试1/2/3/4 组合并训练例子代码输出正好 5 行每行对应一轮所有样本都有且仅有1次被分到测试集保证每个样本都参与过测试评估结果更可靠。注意划分是一次性完成不是每轮重新分程序只会最开始做 1 次全局切分生成 k 组固定子集后续 k 轮只是轮换哪一组当测试不会重新打乱重分。如果开启shuffleTrue仅在最开始划分前打乱一次后续 k 轮分组不变。2. 为什么必须跑满 k 轮如果只跑 1 轮只用 1 组测试评估结果偶然性大跑完 k 轮每个样本都验证过最后取 k 轮指标平均值降低随机误差。总结单次规则全集分 k 份k-1 份合并用于训练、1 份测试完整流程轮换 k 次每份轮流当测试集合计 k 轮。这两点合在一起才是完整的 K 折交叉验证。