FastText查询带@前缀词向量报KeyError 无ngram无法计算OOV向量问题
问题产生的具体原因
- 分词逻辑导致目标词从未进入模型词表
你预处理阶段使用的nltk.WordPunctTokenizer遵循「标点/特殊符号与相邻文本强制拆分」的分词规则,@属于被判定为独立拆分单元的特殊符号,因此你认为存在于语料中的带@前缀完整词汇,实际在分词阶段就被拆碎了:@.poisonjamak会被拆分为['@', '.', 'poisonjamak']@aminagabread会被拆分为['@', 'aminagabread']- 你提到的
@<em>iamquak123</em>还会因为未提前清洗HTML标签,被进一步拆为['@', '<', 'em', '>', 'iamquak123', '</', 'em', '>']
模型训练时接收的是拆分后的token序列,词表中只会收录独立的@、标点碎片、以及去掉@前缀的用户名字段,根本不存在你查询的带@前缀的完整字符串,这类查询词会被直接判定为未登录词(OOV)。
- 参数配置关闭了OOV词的向量计算能力
你训练FastText时设置了max_n=0,该参数会直接关闭FastText核心的字符级n-gram子词建模能力。默认配置下FastText即使遇到未登录词,也可以通过拆解词的字符n-gram片段拼接出近似向量,但关闭该功能后,模型遇到不在词表中的词时没有任何兜底计算逻辑,就会抛出你看到的KeyError: 'cannot calculate vector for OOV word without ngrams'报错。 - 移除@前缀后可以正常查询的原因非常直接:去掉@后的字符串刚好就是分词后实际进入训练的独立token,本身就在模型词表中,自然可以正常返回向量。
如果需要正常获取带@前缀词汇的向量,可以在预处理阶段调整分词规则,将@开头的连续字符(含@、后续关联的用户名、特殊符号)识别为单个token,或提前通过正则匹配把这类@提及实体替换为统一的单token标记后重新训练模型即可。
内容的提问来源于stack exchange,提问作者John Angelopoulos
相关产品推荐
相关产品推荐

