训练集和验证集该怎么分
划分训练集和验证集,是数据建模里最容易被略过的一步。多数人凭感觉取个 8:2 就开工,等模型上线才发现评估结果虚高。问题往往不在模型,而在划分方式本身就引入了偏差。
先问一个问题:数据是不是随时间变化
如果每一行数据都带时间戳,比如交易记录、日志、传感器采样,那么随机划分基本是错的。随机打乱会把未来的数据混进训练集,模型在训练时已经见过「之后」的规律,验证集上的表现自然虚高。
正确做法是按时间切分:用较早的一段做训练,较晚的一段做验证。切分点通常取时间序列的某个位置,比如前 70% 的时间段训练,后 30% 验证。如果业务有明显的周期性,比如按周或按月波动,切分点要落在周期边界上,避免把半个周期切进验证集。
只有一种情况适合随机划分:样本之间没有时间依赖,且采集顺序不携带信息。比如同一批实验条件下重复测量的物理量,打乱顺序不影响结论。
样本量决定验证集留多大
常见的 8:2 和 7:3 只是经验值,真正该看的是验证集里有多少条样本。
- 验证集少于几百条时,评估指标的波动会很大,换一次随机种子结果可能差好几个百分点。
- 验证集在几千条量级时,指标开始稳定,可以用来做模型选择。
- 样本总量本来就只有几百条时,不要硬切验证集,改用交叉验证:把数据分成 k 折,轮流留一折做验证,其余训练。
交叉验证的代价是训练次数变成 k 倍。k 一般取 5 或 10,取太大收益递减,取太小方差偏高。
类别不平衡时必须分层
如果目标变量是分类标签,且各类占比悬殊,纯随机划分可能让验证集里某一类样本极少,甚至一条都没有。这时要用分层抽样:按类别比例分别抽取训练和验证,保证两边类别分布一致。
具体做法是先按标签分组,每组内再随机切分,最后合并。绝大多数机器学习库都提供了带 stratify 参数的划分函数,直接传标签列即可。
回归任务没有类别,但可以按目标值分箱后再分层,保证验证集的目标值范围覆盖完整,而不是全落在中间区间。
验证集不能用来看效果调参
一个常见错误是:在验证集上反复试不同模型、不同超参数,挑出表现最好的一个,然后把这个验证集上的分数当作最终效果。这样验证集实际上变成了训练集的一部分,分数不再可信。
合理的做法是三分:训练集用来拟合参数,验证集用来选模型和调参,另外留一份测试集,只在最后用一次。测试集在调参过程中完全不参与,结果才有参考价值。
如果数据量不够做三分,至少要做到:调参用交叉验证,最终的测试集留到全部流程结束再打开。
检查有没有信息泄露
划分之前,先确认特征里没有混入未来信息或标签信息。典型情况包括:
- 用全局统计量做的特征,比如用全量数据算的均值、分位数,再喂给模型。
- 同一条记录被重复采样,分别落进训练集和验证集。
- 分组数据被拆散,比如同一用户的多次行为被分到两边。
这类泄露不会报错,但会让验证分数明显偏高。检查方法是:如果验证集上的表现好到不合常理,先怀疑划分,而不是先高兴。
划分完做一次快速核对
切分完成后,花几分钟比对两边的分布:目标变量的均值或比例、关键特征的取值范围、类别分布。差异明显就说明划分有问题,要么换切分方式,要么调整随机种子。这一步不复杂,但能挡掉不少后续返工。
相关文章
动手前先建个基准线
这篇讲怎么在开始优化数据流程之前,先建立一个可比较的基准线。内容包括选指标、定口径、留出对照样本,以及基准线失效时怎么判断,让后续每次改动都有据可查。
试得越多越容易碰巧成功
本文讲多重检验下的过拟合问题:为什么试的策略越多,越容易撞上一个看似有效的结果。给出回测中识别与处理这类假阳性的具体做法,包括记录试错次数、样本切分、参数敏感度检查与效应量估计。
回测里的幸存者偏差怎么避免
回测中最隐蔽的误差往往来自数据本身。这篇讲清楚幸存者偏差是怎么混进样本的,给出检查数据集、重建历史成分、设定对照组的可操作方法,尽量在动手之前就把这类误差挡在外面。