使用 gensim 和预训练的 word2vec 模型管理 KeyError

Manage KeyError with gensim and pretrained word2vec model

我使用 wang2vec (https://github.com/wlin12/wang2vec) 预训练了一个词嵌入,并通过 gensim 将其加载到 python 中。当我试图获取一些不在词汇表中的单词的向量时,我显然得到:

KeyError: "word 'kjklk' not in vocabulary"

所以,我想在词汇表中添加一个项目来映射 oov(词汇表外)单词,比方说 <OOV>。由于词汇表采用 Dict 格式,我将简单地添加项目 {"<OOV>":0}

但是,我搜索了一个词条,

model = gensim.models.KeyedVectors.load_word2vec_format(w2v_ext, binary=False, unicode_errors='ignore')
dict(list(model.vocab.items())[5:6])

输出类似于

{'word': <gensim.models.keyedvectors.Vocab at 0x7fc5aa6007b8>}

那么,有没有办法将<OOV>标记添加到通过gensim加载的预训练词嵌入的词汇表中,避免KeyError?我查看了 gensim 文档,发现了这个:https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec.build_vocab 但它似乎不适用于更新参数。

添加一个合成的 '<OOV>' 令牌只会让您查找该令牌,例如 model['<OOV>']。该模型仍然会为 'kjklk'.[=21 等缺少的密钥提供密钥错误=]

没有对添加任何此类 'catch-all' 映射的内置支持。通常,忽略未知标记比使用一些插入值(例如零向量或随机向量)更好。

在 Python 中,通过 in 关键字明确检查密钥是否存在是相当惯用的,如果您想对不存在的密钥执行不同的操作。例如:

vector = model['kjklk'] if 'kjklk' in model else DEFAULT_VECTOR

(值得注意的是,*expr1* if *expr2* else *expr3* 推迟了初始 expr1 的计算,避免了 KeyError。)

Python 也有 defaultdict 变体字典,它可以为任何未知键返回一个默认值。参见:

https://docs.python.org/3.7/library/collections.html#collections.defaultdict

如果行为真的很重要,可以尝试用其中之一替换 KeyedVectors vocab 字典,但可能会对其他代码产生副作用。