为何调整CSV行顺序后torchtext.legacy.text处理同数据集结果不同
现象原因
该差异由dataset.split()的随机划分特性,以及build_vocab()对训练集的强依赖共同导致:
- 当前总样本仅3条,
torchtext.legacy.data.Dataset.split()默认采用随机抽样拆分训练集/测试集,默认拆分比例为0.7,3条样本下会随机抽取2条作为训练集,剩余1条划入测试集。调整CSV行顺序会改变随机抽样的命中结果,哪怕行顺序不变,多次无固定种子的运行也会得到不同的训练集。 TEXT.build_vocab()仅基于传入的train_dataset构建词汇表,两次运行的训练集分别包含/不包含那条带or、just、morning的长文本,最终生成的词汇表收录内容、索引排序自然会有明显差异。
build_vocab()的工作逻辑 torchtext中Field.build_vocab()的执行流程如下:
- 遍历传入数据集的所有对应Field的文本,按照预先定义的规则预处理:你设置的
lower=True会先把所有字符转为小写,tokenize='spacy'会调用spacy分词器把长文本拆分为单个token - 统计所有token的出现频次,按频次从高到低排序,频次相同的token按首次出现的先后顺序排列
- 预留特殊token的索引位:默认索引0为
<unk>(未知词),索引1为<pad>(填充符),之后依次对应排序后的常规token - 生成
stoi(字符串转索引)和itos(索引转字符串)两个映射表
结果复现的优化方案
如果要避免随机划分导致的词汇表波动,可采用以下两种方案:
- 固定拆分随机种子:调用
split()时传入固定随机状态,示例:train_dataset, test_dataset = dataset.split(random_state=42),保证每次运行的训练集样本完全一致 - 小样本场景下直接用全量数据集构建词汇表:跳过拆分步骤,直接调用
TEXT.build_vocab(dataset),基于所有样本生成词汇表
内容的提问来源于stack exchange,提问作者Bibek Chalise
相关产品推荐
相关产品推荐

