在 Gensim Word2Vec 词汇表中组合向量

问题描述

Gensim Word2Vec 模型有一个很好的方法,它可以让您在给定正面词和负面词列表的情况下找到模型词汇表中前 n 个最相似的词。

wv.most_similar(positive=['word1','word2','word3'],negative=['word4','word5'],topn=10)

我想要做的是创建词向量,表示输入正负词的平均或求和向量。我希望使用这个新向量与其他向量进行比较。 像这样:

newVector = 'word1' + 'word2' + 'word3' - 'word4' - 'word5'

我知道向量可以求和,但我不确定这是否是最佳选择。我希望确切地找出上述函数(most_similar)如何组合正向量和负向量,以及 Gensim 是否具有这样做的功能。提前致谢。

解决方法

Gensim 没有像 most_similar() 那样公开一个单独的函数来添加/减去(单位规范的)向量。

也许应该这样做,因为这通常很有用,包括在其他现有方法之间共享代码。

但作为一个开源项目,您可以查看该操作的确切 Python 代码,并将其用作您自己计算的模型。

有关定义该函数的当前代码,请参阅:

https://github.com/RaRe-Technologies/gensim/blob/ee3d6fd1e33fe39fc7aa31ebd56bd63b1a2a2ed6/gensim/models/keyedvectors.py#L687

,

根据上面的建议,我选择查看 Gensim 源代码并复制他们用于平均向量的方法。这是代码柜面它可以帮助其他人。 注意:此代码是从 gensim 复制的,只是重新格式化以返回平均向量。

from gensim import matutils
import numpy as np
from numpy import ndarray,array,float32 as REAL

KEY_TYPES = (str,int,np.integer)

'''
FUNCTION : meanVector(...)
INPUT :
        keyedVectors : word vectors or keyed vectors from gensim model,(model.wv)
        positive : list of words or vectors to be applied positively [default = list()]
        negative : list of words or vectors to be applied negatively [default = list()]
OUTPUT : 
        averaged word vector,[type = numpy.ndarray]
DESCRIPTION :
        allows for simple averaging of positive and negative words and vectors given a gensim model's word vector library.
'''

def meanVector(keyedVectors,positive=list(),negative=list()):
        
    positive = [
            (item,1.0) if isinstance(item,KEY_TYPES + (ndarray,))
            else item for item in positive
            ]
    negative = [
            (item,-1.0) if isinstance(item,))
            else item for item in negative
            ]
        
    # compute the weighted average of all keys
    all_keys,mean = set(),[]
    for key,weight in positive + negative:
        if isinstance(key,ndarray):
            mean.append(weight * key)
        else:
            mean.append(weight * keyedVectors.get_vector(key,norm=True))
            if keyedVectors.has_index_for(key):
                all_keys.add(keyedVectors.get_index(key))
        if not mean:
            raise ValueError("cannot compute similarity with no input")
        
    mean = matutils.unitvec(array(mean).mean(axis=0)).astype(REAL)

    return mean

注意:这还没有经过彻底的测试。