事情本身不复杂,线索都在日志里。标注回归集有 2000 条,跑出来准确率 0.94,上线后线上抽样只有 0.71。对比后发现回归集里有 12% 的样本和训练集文本完全相同,还有一部分是同一条内容的不同切分。换一个随机种子重划分之后,泄漏比例仍有 9%。
第一反应是「近重复只做了完全匹配,改个标点就逃过检查」,验证下来不成立。
把日志和配置对完,能解释这个现象的基本就这几处。划分时按条随机,同一份原文被分到了两边。也可能是训练集与回归集都用同一份原始语料切分而来。
少数情况下是回归集里混入了人工复述过的同义样本。
第一件事是按文本指纹查完全重复
python -c "import hashlib,json;a={hashlib.md5(json.loads(l)['text'].encode()).hexdigest() for l in open('train.jsonl')};b=[json.loads(l) for l in open('test.jsonl')];print(sum(1 for r in b if hashlib.md5(r['text'].encode()).hexdigest() in a))"
再往下改成按文档 id 分组划分
python -c "print('GroupShuffleSplit by doc_id')"
接着对近重复再跑一次指纹比对
python -c "print('hamming distance <= 3 drop')"
去掉泄漏样本后复测准确率
python -c "print('acc 0.94 -> 0.73')"
恢复的判定其实很直接。回归集与训练集的完全重复降到 0,近重复比例低于 1%,复测准确率 0.73 与线上抽样接近。
回归集要按文档而不是按条划分,同一份原文切出的多条样本分到两边,指标必然虚高。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
