2017-10-09 63 views
0

我有很多词矢量的Word2Vec模型。我可以像这样访问一个单词向量。如何手动改变一个词的向量尺寸Gensim 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 [ '男孩']一个适当的矢量表示。

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

但下面的错误被抛出

TypeError: 'Word2Vec' object does not support item assignment 

是否有任何方式或变通方法来做到这一点?一旦模型被训练,那就是手动操纵单词向量?在除Gensim之外的其他平台上可能吗?

回答

2

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

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

具体而言,原始字向量(在最新版本的gensim)存储在称为wvWord2Vec对象的属性,并且该wv属性是KeyedVectors一个实例。如果你检查它的源代码,你可以看到串键字向量的访问(例如'boy'),包括那些由[] -indexing由__getitem__()方法来实现,都要经过它的方法word_vec()。您可以在本地安装,或者在Github上查看该方法的来源:

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

在那里你会看到这个词实际上被转换成整数索引(通过self.vocab[word].index),然后用于访问内部的syn0syn0norm数组(取决于用户是访问原始的还是单位归一化的矢量)。如果你看看其他地方,这些地方都设置了,或者干脆检查它们在自己的控制台/代码(仿佛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字典