如何在 Gensim Word2Vec 中手动更改单词的向量维度

How to manually change the vector dimensions of a word in Gensim Word2Vec

我有一个包含很多词向量的 Word2Vec 模型。我可以这样访问一个词向量。

word_vectors = gensim.models.Word2Vec.load(wordspace_path)
print(word_vectors['boy'])

输出

[ -5.48055351e-01   1.08748421e-01  -3.50534245e-02  -9.02988110e-03...]

现在我有了一个合适的矢量表示,我想用它替换 word_vectors['boy']。

word_vectors['boy'] = [ -7.48055351e-01   3.08748421e-01  -2.50534245e-02  -10.02988110e-03...]

但是抛出如下错误

TypeError: 'Word2Vec' object does not support item assignment

是否有任何时尚或解决方法可以做到这一点?那是在训练模型后手动操作词向量?在 Gensim 之外的其他平台上可以吗?

由于 word2vec 向量通常仅由迭代训练过程创建,然后被访问,gensim Word2Vec 对象不支持通过其单词索引直接分配新值。

然而,正如它在 Python 中一样,它的所有内部结构都完全由您 viewable/tamperable 完成,并且由于它是开源的,您可以准确地查看它是如何完成所有现有的功能,并将其用作如何做新事物的模型。

具体来说,原始词向量(在最新版本的 gensim 中)存储在名为 wvWord2Vec 对象的 属性 中,而这个 wv 属性 是 KeyedVectors 的实例。如果你检查它的源代码,你可以看到通过字符串键(例如 'boy')访问词向量,包括那些通过 __getitem__() 方法实现的 []-索引,通过它方法word_vec()。您可以在本地安装或 Github:

查看该方法的源代码

https://github.com/RaRe-Technologies/gensim/blob/c2201664d5ae03af8d90fb5ff514ffa48a6f305a/gensim/models/keyedvectors.py#L265

在那里你会看到这个词实际上被转换成一个整数索引(通过self.vocab[word].index)然后用于访问内部syn0syn0norm数组(取决于是否用户正在访问原始或单位标准化向量)。如果您在其他地方查看这些设置的位置,或者只是在您自己的 console/code 中检查它们(就像 word_vectors.wv.syn0),您会看到这些是 numpy 个数组,其中 do支持索引直接赋值

所以,你可以通过整数索引直接篡改它们的值,就好像通过:

word_vectors.wv.syn0[word_vectors.wv.vocab['boy'].index] = [ -7.48055351e-01   3.08748421e-01  -2.50534245e-02  -10.02988110e-03...]

然后,以后对 word_vectors.wv['boy'] 的访问将 return 您的更新值。

备注:

• 如果您希望更新 syn0norm,以获得适当的单位范数向量(如在 most_similar() 和其他操作中使用的那样),最好修改 syn0 首先,然后丢弃并重新计算 syn0norm,通过:

word_vectors.wv.syn0norm = None
word_vectors.wv.init_sims()

• 添加新词需要更多涉及的对象篡改,因为它需要增长 syn0(用更大的数组替换它),并更新 vocab dict