训练集和测试集重复怎么查?按编号和内容指纹分别核对

分别查训练集与测试集的编号交集、规范化内容哈希交集,导出命中对和标签冲突;给出完整代码,并说明近似重复与相关样本泄漏仍需另外核查。

检查训练集和测试集是否重复,要分别查业务编号交集和内容指纹交集。同一编号可能被两次导出;相同文本也可能换了编号。只检查其中一层,都可能留下跨集合重复。

下面的目标是审计已经划分好的两个集合,输出可追查的命中对。它不会自动删除样本;应该先查清重复来源和标签冲突,再重新划分、训练与评估。

训练集和测试集重复怎么查?按编号和内容指纹分别核对

准备两份数据,先固定比较口径

示例使用 train、test 两张小表,每行有 id、text、label。六行都是虚构输入;代码已在 Windows、Python 3.11.15、pandas 3.0.6 下实际运行。真实文件中的 id 必须在两个集合中使用相同业务含义,编号 001 不能在一个集合表示用户、另一个集合表示文本。

内容指纹只包含模型实际看到的文本,不把标签、随机编号或 split 名称混进去。标签不同而文本相同也需要被找到;把标签写进指纹,反而会漏掉这种冲突。

本例仅做 NFKC 规范化与连续空白折叠,随后用 SHA-256。这样“退款 进度”和含全角空格的“退款 进度”会被归为同一内容。规范化规则是本任务的明确选择,可能改变某些技术文本或符号的区别;用于你的语料前,先用少量真实样本核对规则是否保留了任务需要的差异。

运行编号与内容两层核查

在空目录建立环境,把完整代码保存为 check_split_duplicates.py,再运行:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install pandas==3.0.6
.\.venv\Scripts\python.exe check_split_duplicates.py

macOS 或 Linux 用 python3 创建环境,并用 .venv/bin/python 运行。Python hashlib 官方文档给出 SHA-256 和 hexdigest 的接口;pandas.merge 官方文档说明 one_to_one 唯一性检查,也提醒空键会彼此匹配。因此代码在连接之前先拒绝缺失编号和文本。

import hashlib
import re
import unicodedata
import pandas as pd

train = pd.DataFrame({
    'id':['T001','T002','T003'],
    'text':['退款 进度','物流跟踪','更换地址'],
    'label':[1,0,0]
})
test = pd.DataFrame({
    'id':['T002','T900','T901'],
    'text':['物流跟踪','退款\u3000进度','全新问题'],
    'label':[0,0,1]
})
def fingerprint(text):
    # Only NFKC + whitespace folding; do not include the label.
    value = unicodedata.normalize('NFKC', text)
    value = re.sub(r'\s+', ' ', value).strip()
    return hashlib.sha256(value.encode('utf-8')).hexdigest()

for name, frame in [('train',train),('test',test)]:
    if frame[['id','text','label']].isna().any().any():
        raise ValueError(f'{name}: missing ID/text/label')
    if frame['id'].duplicated().any():
        raise ValueError(f'{name}: IDs are not unique')
    if not frame['id'].map(lambda x: isinstance(x,str) and bool(x.strip())).all():
        raise ValueError(f'{name}: invalid ID')
    if not frame['text'].map(lambda x: isinstance(x,str) and bool(x.strip())).all():
        raise ValueError(f'{name}: blank or non-string text')
    frame['fp'] = frame['text'].map(fingerprint)
id_hits = train.merge(test,on='id',suffixes=('_train','_test'),validate='one_to_one')
content_hits = train.merge(test,on='fp',suffixes=('_train','_test'))
content_hits['label_conflict'] = content_hits['label_train'] != content_hits['label_test']
print('id_overlap=', sorted(id_hits['id'].tolist()))
print(content_hits[['id_train','id_test','label_conflict']].sort_values(
    ['id_train','id_test']).to_string(index=False))
content_hits.to_csv('cross_split_duplicate_audit.csv',index=False,encoding='utf-8-sig')
assert len(id_hits) == 1
assert len(content_hits) == 2
assert content_hits['label_conflict'].sum() == 1

结果为什么是一个编号命中、两个内容命中?

id_overlap= ['T002']
id_train id_test  label_conflict
    T001    T900            True
    T002    T002           False

T002 同时在两个集合里,所以编号检查命中一次。内容检查还找到训练集 T001 与测试集 T900:编号不同,规范化后的文本相同,标签分别为 1 和 0,label_conflict 为 True。

运行后打开 cross_split_duplicate_audit.csv,逐对核对两个来源编号、原始文本和标签。不要直接把两种检查的行数相加当作重复样本数:T002 在两层中都命中了,计数对象是命中关系而不是互不重复的样本。

内容相同且同集重复很多时,连接会生成多对关系,内存开销可能迅速增长。大语料可先按指纹汇总每个集合的样本数,再按需要展开命中对;本例适合先理解流程和检查小表。

发现重复之后,怎么处理才能继续评测?

  1. 冻结当前文件,保存命中表和规范化规则,追查各样本来源。
  2. 区分真实重复、同一用户多条记录、公共固定短语和标签冲突。短文本相同不一定表示同一个事件,人工复核原始上下文。
  3. 对同源或高度关联样本制定统一分组规则,让相关样本进入同一集合;需要评估新用户时按用户分组,需要评估未来数据时按时间规划。
  4. 修正标签争议并重新建立独立测试集,从头重新训练。已经受污染的测试分数不能靠事后删除几行就恢复可信。
  5. 对新划分再次运行编号和指纹检查,并记录样本变化与评估版本。

如果只检查编号,换编号的复制文本会漏掉;如果只检查规范化后相同的哈希,改写文本、相似图片和同一用户的不同记录会漏掉。哈希检查检测的是所选规范化规则下的精确相同,不是语义近似重复检测。

报错和没有命中,分别应该怎么判断?

  • Missing ID/text/label:先隔离缺失行,修正来源;不要用空字符串统一填编号。
  • IDs are not unique:编号在集合内已有重复,先查清编号粒度;one_to_one 不应强行改成 many_to_many 绕过。
  • 读取后编号变成数字:用 pd.read_csv(…, dtype={“id”: “string”}) 保留前导零,并检查导出时是否已经损失原值。
  • 没有命中:只能说明这两种规则没发现问题,不能证明没有目标泄漏、时间泄漏或相关样本泄漏。

如果输入改成多列特征,先选择预测时可用的特征列,再按稳定列顺序和一致缺失值规则序列化;不要直接对整行包含标签的 CSV 字符串哈希,也不要忽略字符串“1”和数字 1 的类型差别。

能否只删除测试集里命中的记录?

正式评测需要先确定原因。删除会改变测试样本分布,还可能保留同源近似重复;如果训练时已经看过测试相关内容,应重新划分并重新训练。只有在可解释的数据治理规则下处理好来源、标签与分组,新的评估结果才有明确含义。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30611.html

赞 (0)
AI小管家的头像AI小管家
训练数据是否缺少某类人群?用交叉表核对分组与标签覆盖
上一篇 9小时前
没有 GPU 怎么学神经网络?用 MLPClassifier 跑通 CPU 示例
下一篇 9小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部