You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据集更新时如何稳定拆分训练测试集及交叉验证问题

增量数据集拆分一致性相关问题解答

问题背景

我正在学习《Hands-On Machine Learning with Scikit-Learn and TensorFlow 第二版》的配套代码,在训练集与测试集划分章节中,作者强调拆分函数的设计需要满足:即使数据集发生刷新更新,多次运行得到的测试集也能保持一致。书中给出的代码可在数据集更新后,仍按照设定的test ratio比例拆分训练集与测试集,且新的测试集不会包含任何此前划分到训练集的样本。
其实现逻辑为:为每个样本的索引值(identifier/id_x)计算哈希值,若该值落在可选数值范围0到test ratio占比的对应区间内,则判定该样本属于测试集,对应实现代码如下:

from zlib import crc32

def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))
    return data.loc[~in_test_set], data.loc[in_test_set]

我对上述逻辑已经理解,但存在三个核心疑问:

  • 如何使用sklearn的train_test_split函数实现同等效果:即当全量数据集更新后,测试集始终不会包含之前已经被划分到训练集的样本?
  • 如果传入random_state参数,同时保证数据集更新时仅在原有数据基础上新增行、永不删除原有行,是否就能自动实现该效果?
  • 这种“仅新增不删除”的要求在实际业务场景中是否具备可行性?交叉验证场景下是否也需要考虑这类数据泄露问题?

具体解答

1. 仅靠train_test_split加固定random_state无法实现增量数据集的拆分一致性

train_test_split的底层逻辑是对传入的全量数据集做整体伪随机乱序后按比例切分,只要数据集长度发生变化——哪怕只是在末尾新增行、完全不改动原有行的内容和顺序——固定random_state生成的乱序索引映射关系也会整体偏移。举个最简单的例子:原本有1000条样本,设置random_state=42拆分后80%划入训练集、20%划入测试集;当你新增200条样本凑够1200条后,再用同一个random_state拆分,伪随机数生成器会针对1200长度的序列重新生成乱序索引,原本在训练集的旧样本大概率会被划入新的测试集,完全达不到哈希拆分的新旧样本无交叉的效果。
如果要基于sklearn原生组件实现和书中哈希拆分一致的效果,不需要依赖train_test_split,可以直接使用sklearn.model_selection.GroupShuffleSplit:提前给每个样本分配全局唯一、永不更改复用的样本id作为分组标识,拆分时保证同一个分组的样本不会同时出现在训练集和测试集,只要旧样本id保持不变、新增样本分配新的唯一id,就能实现和手写crc32哈希函数完全一致的拆分效果。

2. “仅新增不删除原有行”的业务可行性分场景判断

  • 对于日志类、用户行为采集类、时序交易类数据集:这个要求天然成立,这类数据本身就是仅追加写入(append-only)的,原始数据入库后不会做删除或修改,只要给每条入库数据分配全局唯一、永不复用的id,哈希拆分的逻辑可以直接落地。
  • 对于需要做数据清洗、去重、标签修正的数据集:这个要求不天然成立,比如发现旧样本标签标注错误需要修正、或者发现重复采集的样本要删除,原有数据集的行就会发生变动。此时不需要强行要求行位置不变,只需要在数据清洗层固定样本id的映射规则:哪怕样本位置变化、内容修正,只要对应同一个现实实体的样本,就保留原来的id;被删除的样本id直接作废不复用,依然可以保证拆分一致性。

3. 交叉验证场景必须考虑同类数据泄露问题

交叉验证时如果不做固定分组的约束,一样会出现信息泄露,导致验证结果不可靠:

  • 如果是时序类数据集,普通的随机交叉验证会把未来时间点的数据分到训练集、过去时间点的数据分到验证集,本质和测试集混入旧训练样本的泄露逻辑一致,此时必须使用时序分割的交叉验证策略,保证训练折的样本时间全部早于验证折。
  • 如果数据集存在重复样本、或者同一个用户/实体对应多条样本,随机拆分可能会让同一个实体的样本同时出现在训练折和验证折,会导致验证集分数虚高,此时需要用分组交叉验证GroupKFold,按实体id做拆分,和测试集拆分时按id哈希的逻辑保持一致。

内容的提问来源于stack exchange,提问作者thedelstar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:03:27