如果让学生先看考试原题,再用同一套题评价学习效果,得到的高分并不能说明他真正掌握了知识。
机器学习也一样。为了知道模型能否处理没见过的数据,需要把数据分开使用。
视频讲解:在官网观看本课视频
训练集:让模型学习
训练集参与参数更新。
模型反复读取训练样本,计算预测误差,再根据误差调整参数。训练集通常占数据的最大部分。
模型在训练集上表现越来越好,只能说明它越来越熟悉这些训练数据,并不代表它能处理新数据。
验证集:帮助选择方案
验证集不用于直接更新模型参数,而是帮助我们做选择,例如:
-
使用几层网络;
-
学习率设置多少;
-
训练多少轮;
-
选择哪个模型版本;
-
是否需要提前停止训练。
因为会反复根据验证结果调整方案,模型开发过程实际上也在间接适应验证集。
测试集:最后一次检查
测试集用于最终评估。它应该尽量模拟模型上线后真正遇到的新数据。
测试集不应该参与选模型、调参数或决定训练轮数。否则它就不再是独立的最终考试。
常见划分比例
没有适合所有项目的固定比例,常见起点包括:
训练集 70% / 验证集 15% / 测试集 15%
训练集 80% / 验证集 10% / 测试集 10%
数据很少时可以使用交叉验证。时间序列数据则不能随意打乱,通常需要按照时间先后划分。
划分前还要注意分布
分类任务中,如果某个类别本来就很少,随机划分后可能全部落在某一个集合里。可以使用分层抽样,让各集合中的类别比例更接近。
重复样本、同一用户数据或同一来源图片也可能跨集合泄漏,需要根据业务关系分组划分。
技术图:把关键链路画清楚

可运行实验:用分层划分保留类别比例
分类数据不应只随机切一刀。类别不平衡时,分层划分能让训练集和测试集保留接近的正负样本比例。
from collections import Counter
from sklearn.model_selection import train_test_split
X = list(range(20))
y = [0] * 14 + [1] * 6
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.30, random_state=42, stratify=y
)
print("训练集:", len(X_train), Counter(y_train))
print("测试集:", len(X_test), Counter(y_test))
运行结果:
训练集: 14 Counter({0: 10, 1: 4})
测试集: 6 Counter({0: 4, 1: 2})
两部分都保留了接近 7:3 的类别比例。真实项目还要按用户、设备或时间分组,防止同一实体同时出现在不同集合。
常见误区
测试集可以反复用于调参。看得越多,测试集越接近训练信息。
随机划分一定公平。时间序列、同源图片和用户行为数据通常需要按组或时间切分。
动手练习
去掉 stratify=y,更换多个随机种子,观察小数据集里类别比例如何波动。
这一课先记住什么
-
训练集学习参数;
-
验证集选择方案;
-
测试集进行最终评估。
下一课会回答:模型做完分类后,除了准确率,我们还应该看哪些指标?
本文首发于「去你想去的地方」: 训练集、验证集和测试集分别做什么? | 去你想去的地方
完整学习路线、视频版和后续更新请访问原文。


