使用gensim操作GoogleNews词向量遇疑难:缺失词处理及模型扩展
关于GoogleNews词向量缺失词与嵌入追加的问题解答
嘿,我来帮你逐个拆解这些问题:
1. 明明存在缺失词,为何missing_embd为空?
问题出在你初始化word_to_idx的代码逻辑里!你先创建了一个包含所有语料词、值为0的有序字典,紧接着又重新赋值了一个只包含模型中存在的词的字典——这直接把所有缺失词的键都丢掉了!
你原来的代码:
word_to_idx=OrderedDict({w:0 for w in corpus_words}) word_to_idx=OrderedDict({w:model.wv.vocab[w].index for w in corpus_words if w in model.wv.vocab})
这段代码执行后,word_to_idx里只剩下模型中存在的词,根本没有值为0的键,遍历的时候自然找不到缺失词,missing_embd当然是空的。
正确的写法应该是先初始化所有词为0,再逐个替换存在的词的索引:
from collections import OrderedDict word_to_idx = OrderedDict({w: 0 for w in corpus_words}) for w in corpus_words: if w in model.wv.vocab: word_to_idx[w] = model.wv.vocab[w].index
这样缺失词的value会保留为0,后续遍历就能正常抓到它们了。
2. GoogleNews词表会缺失"to"这类常见词吗?
绝对不会!GoogleNews-vectors-negative300.bin(注意你写错了文件名,是300不是33)包含几乎所有常用功能词,"to""a""the"这类高频词肯定在词表里。
你遇到KeyError的原因大概率是模型加载出错:
- 首先,方法名写错了:应该是
word2vec.KeyedVectors.load_word2vec_format(首字母小写的load,不是大写的Load),大小写错误可能导致模型没有正确加载。 - 其次,文件名错误:官方的预训练模型是
GoogleNews-vectors-negative300.bin,你写的33明显是笔误,文件路径或名称不对的话,加载的模型要么不完整,要么根本不是正确的GoogleNews向量。
建议你检查文件名和加载方法,重新加载模型后再测试model["to"],应该就能正常输出向量了。
3. 如何向word2vec模型追加新嵌入?
你之前尝试的build_vocab和syn0方法都有问题:
build_vocab(word, update=True)是错的:build_vocab需要传入的是语料(比如嵌套列表形式的句子),不是单个词,而且这个方法主要用于训练阶段扩展词汇,不适合给预训练模型加新向量。syn0是gensim旧版本的属性,新版本已经被vectors替代,直接修改它会无效甚至报错。
正确的做法(分gensim版本):
如果你用的是gensim >= 4.0版本(推荐):
可以直接用add_vectors方法批量添加新词汇和对应的嵌入:
# 整理缺失词和它们的嵌入 new_words = list(missing_embd.keys()) new_vectors = [missing_embd[word] for word in new_words] # 追加到模型中 model.add_vectors(new_words, new_vectors)
如果你用的是gensim < 4.0版本:
需要手动扩展vocab和vectors属性,步骤如下:
import numpy as np # 1. 扩展词汇表 for word in missing_embd.keys(): # 为新词汇创建Vocab对象 model.wv.vocab[word] = model.wv.Vocab(index=len(model.wv.vocab)) # 2. 扩展向量矩阵 new_vectors = np.array(list(missing_embd.values())) model.wv.vectors = np.vstack([model.wv.vectors, new_vectors])
另外要注意:用相似词均值生成缺失词嵌入的方法虽然可行,但效果不一定好——如果缺失词是领域特定词汇,相似词可能和它语义偏差较大,你可以考虑用fastText这类本身支持OOV(未登录词)的预训练模型,或者用自己的语料对缺失词进行微调。
内容的提问来源于stack exchange,提问作者Mahsa
相关产品推荐
相关产品推荐

