Spacy en_core_web_lg模型词向量相似度输出异常如何解决
问题原因
你遇到的结果不符合预期、出现残留词的问题,和模型安装、环境配置无关,核心是两个代码逻辑错误:
- 遍历对象错误:spaCy的
nlp.vocab是动态缓存的词表,采用懒加载机制,初始化模型时不会把所有预训练词向量加载到这个对象里,只会把你运行代码过程中接触到的词(比如之前写过的代码里的零散词、之前测试用的wolf/cat等)缓存进去。你遍历nlp.vocab计算相似度时,本质是在极小的已缓存词池里排序,根本没覆盖模型自带的全量预训练词,自然会出现大量无意义词、之前测试的残留词。 - 过滤规则太松:原代码只过滤了无向量、非小写、非纯字母的词,没有排除长度过短的口语缩略词、停用词,这类词在预训练语料里出现频率极高,向量分布和很多向量的余弦距离都偏近,很容易挤入Top10结果。
修复方案
按以下两点修改代码即可得到预期结果:
- 不要遍历动态缓存的
nlp.vocab,改为遍历nlp.vocab.vectors,这个属性存储的是模型自带的全量预训练静态向量表,不会受运行过程的缓存影响。 - 补全过滤规则,排除停用词、长度小于3的短词,避免无意义词汇干扰排序。
修复后的可运行代码如下:
import spacy from scipy import spatial nlp = spacy.load('en_core_web_lg') cosine_similarity = lambda x, y: 1 - spatial.distance.cosine(x, y) # wolf - dog + cat 测试案例 word1 = nlp.vocab['wolf'].vector word2 = nlp.vocab['dog'].vector word3 = nlp.vocab['cat'].vector new_vector = word1 - word2 + word3 computed_similarities = [] # 遍历全量预训练向量表 for word_id in nlp.vocab.vectors.keys(): word = nlp.vocab[word_id] # 过滤规则:有向量、纯字母、小写、非停用词、长度≥3 if all([ word.has_vector, word.is_lower, word.is_alpha, not word.is_stop, len(word.text) >= 3 ]): sim = cosine_similarity(new_vector, word.vector) computed_similarities.append((word.text, sim)) # 按相似度降序排序取Top10 computed_similarities.sort(key=lambda x: -x[1]) print([item[0] for item in computed_similarities[:10]])
运行上述代码即可得到和课程一致的、以犬科/猫科野生动物相关词汇为主的结果。测试king - man + woman类的词向量类比案例时,只需要替换对应的三个词向量即可,输出会包含queen、prince等符合语义预期的词汇。
如果是在Jupyter Notebook等交互环境运行,不需要反复重装模型、重建环境,采用上述遍历静态向量表的写法就可以完全避免之前运行的词缓存干扰结果。
内容的提问来源于stack exchange,提问作者ryyash
相关产品推荐
相关产品推荐

