4

我有一个带有很多词向量的 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 之外的其他平台上使用?

4

1 回答 1

10

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

但是,就像在 Python 中一样,它的所有内部结构都是完全可见/可篡改的,并且由于它是开源的,您可以准确地查看它是如何完成所有现有功能的,并将其用作如何实现的模型做新的事情。

具体来说,原始词向量(在最新版本的 gensim 中)存储在Word2Vec名为 的对象的属性中wv,该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数组(取决于用户是访问原始向量还是单位归一化向量)。如果您查看设置这些的其他位置,或者只是在您自己的控制台/代码中检查它们(就像 by word_vectors.wv.syn0),您会看到这些numpy数组确实支持按索引直接分配。

因此,您可以通过整数索引直接篡改它们的值,就像通过:

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']将返回您更新的值。

笔记:

• 如果您想syn0norm更新,以获得正确的单位范数向量(用于most_similar()和其他操作),最好先修改syn0,然后丢弃并重新计算syn0norm,方法是:

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

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

于 2017-10-09T18:03:08.827 回答