如何向gensim.models.keyedvectors添加新单词向量并计算most_like

时间:2019-06-17 23:26:44

标签: python gensim word2vec doc2vec

根据Gensim's page on WordEmbeddingKeyedVectors,您可以递增地添加新单词向量的新键值对。但是,在使用预先训练的向量及其标签初始化WordEmbeddingKeyedVectors并向其添加新的,看不见的模型推断词向量之后,most_similar方法将不再可用。

from gensim.models.keyedvectors import WordEmbeddingsKeyedVectors

test = WordEmbeddingsKeyedVectors(vector_size=3)

test.add(entities=["1", "2"], weights=[np.random.randint(5, size=3), 
                                  np.random.randint(5, size=3)])

test.most_similar("2") #THIS WORKS

test.add(entities=['3'], weights=[np.random.randint(5, size=3)])

test.most_similar("3") #THIS FAILS

我希望输出是与输入标签最相似的矢量标签列表,但输出为:

  

IndexError:索引2超出了大小为2的轴0的边界

2 个答案:

答案 0 :(得分:0)

看来add()操作并未清除由most_similar()类操作创建并重复使用的归一化到单位长度向量的缓存。

在执行add()之前或之后,您可以使用以下命令明确删除该缓存:

del test.vectors_norm

然后,您的test.most_similar('3')应该在没有IndexError的情况下工作。

(我已经added a bug-report for this problem到了gensim项目。)

答案 1 :(得分:0)

事实上,我已经找到了解决方案。

gensim.models.keyedvectors文件的class WordEmbeddingKeyedVectors下,我们可以更改

def init_sims(self, replace=False):
    """Precompute L2-normalized vectors."""
    if getattr(self, 'vectors_norm', None) is None or replace:
        logger.info("precomputing L2-norms of word weight vectors")
        self.vectors_norm = _l2_norm(self.vectors, replace=replace)

def init_sims(self, replace=False):
    """Precompute L2-normalized vectors."""
    if getattr(self, 'vectors_norm', None) is None or replace:
        logger.info("precomputing L2-norms of word weight vectors")
        self.vectors_norm = _l2_norm(self.vectors, replace=replace)
    elif (len(self.vectors_norm) == len(self.vectors)): #if all of the added vectors are pre-computed into L2-normalized vectors
        pass 
    else: #when there are vectors added but have not been pre-computed into L2-normalized vectors yet
        logger.info("adding L2-norm vectors for new documents")
        diff = len(self.vectors) - len(self.vectors_norm)
        self.vectors_norm = vstack((self.vectors_norm, _l2_norm(self.vectors[-diff:])))

基本上,原始功能是在没有self.vectors_norm的情况下进行的,它是通过L2归一化self.vectors来计算的。但是,如果self.vectors中有任何新添加的向量尚未预先计算为L2归一化向量,则应预先计算它们,然后将其添加到self.vectors_norm中。

我会将其作为注释发布到您的bug报告@gojomo并添加拉取请求!谢谢:)