【问题标题】:Matching words and vectors in gensim Word2Vec model在 gensim Word2Vec 模型中匹配单词和向量
【发布时间】:2016-12-04 13:39:03
【问题描述】:

我已经让gensim Word2Vec 实现为我计算了一些词嵌入。据我所知,一切都非常奇妙。现在我正在对创建的词向量进行聚类,希望得到一些语义分组。

下一步,我想查看每个集群中包含的单词(而不是向量)。 IE。如果我有嵌入向量[x, y, z],我想找出这个向量代表的实际单词。我可以通过调用model.vocab 和通过model.syn0 获取单词向量。但我找不到明确匹配这些的位置。

这比我预期的要复杂,我觉得我可能错过了明显的方法。任何帮助表示赞赏!

问题:

将单词与Word2Vec () 创建的嵌入向量匹配——我该怎么做?

我的做法:

创建模型后(代码如下*),我现在想将分配给每个单词的索引(在build_vocab() 阶段)与输出为model.syn0 的向量矩阵相匹配。 因此

for i in range (0, newmod.syn0.shape[0]): #iterate over all words in model
    print i
    word= [k for k in newmod.vocab if newmod.vocab[k].__dict__['index']==i] #get the word out of the internal dicationary by its index
    wordvector= newmod.syn0[i] #get the vector with the corresponding index
    print wordvector == newmod[word] #testing: compare result of looking up the word in the model -- this prints True
  • 有没有更好的方法来做到这一点,例如通过将向量输入到模型中来匹配单词?

  • 这甚至能让我得到正确的结果吗?

*我创建词向量的代码:

model = Word2Vec(size=1000, min_count=5, workers=4, sg=1)
        
model.build_vocab(sentencefeeder(folderlist)) #sentencefeeder puts out sentences as lists of strings

model.save("newmodel")

我发现this question 很相似,但还没有真正得到回答。

【问题讨论】:

    标签: python vector machine-learning gensim word2vec


    【解决方案1】:

    我找了很久才找到syn0矩阵和词汇表之间的映射...这里是答案:使用model.index2word这只是按正确顺序排列的单词列表!

    这不在官方文档中(为什么?),但可以直接在源代码中找到:https://github.com/RaRe-Technologies/gensim/blob/3b9bb59dac0d55a1cd6ca8f984cead38b9cb0860/gensim/models/word2vec.py#L441

    【讨论】:

      【解决方案2】:

      如果您只想将 word 映射到 vector,您可以简单地使用 [] 运算符,例如model["hello"]会给你hello对应的向量。

      如果您需要从向量中恢复一个单词,您可以按照您的建议遍历您的向量列表并检查匹配项。但是,这是低效的,而且不是 Python 的。一个方便的解决方案是使用 word2vec 模型的similar_by_vector 方法,像这样:

      import gensim
      
      documents = [['human', 'interface', 'computer'],
       ['survey', 'user', 'computer', 'system', 'response', 'time'],
       ['eps', 'user', 'interface', 'system'],
       ['system', 'human', 'system', 'eps'],
       ['user', 'response', 'time'],
       ['trees'],
       ['graph', 'trees'],
       ['graph', 'minors', 'trees'],
       ['graph', 'minors', 'survey']]
      
      model = gensim.models.Word2Vec(documents, min_count=1)
      print model.similar_by_vector(model["survey"], topn=1)
      

      哪个输出:

      [('survey', 1.0000001192092896)]
      

      其中数字代表相似度。

      但是,这种方法仍然效率低下,因为它仍然需要扫描所有的词向量来搜索最相似的词向量。解决您的问题的最佳方法是在聚类过程中找到一种方法来跟踪您的向量,这样您就不必依赖昂贵的反向映射。

      【讨论】:

      • 谢谢!我找到的那个!不,我只需要让它反过来工作:放入一个向量,取出一个词......
      • 这是可能的,我已经更新了我的帖子来展示如何做。但是如果你能找到一种方法来跟踪你的向量,你会好很多,因为反向映射很昂贵。
      【解决方案3】:

      所以我找到了一个简单的方法来做到这一点,nmodel 是你的模型的名称。

      #zip the two lists containing vectors and words
      zipped = zip(nmodel.wv.index2word, nmodel.wv.syn0)
      
      #the resulting list contains `(word, wordvector)` tuples. We can extract the entry for any `word` or `vector` (replace with the word/vector you're looking for) using a list comprehension:
      wordresult = [i for i in zipped if i[0] == word]
      vecresult = [i for i in zipped if i[1] == vector]
      

      这是基于gensim code。对于较旧版本的 gensim,您可能需要在模型后删除 wv

      【讨论】:

        【解决方案4】:

        正如@bpachev 提到的,gensim 确实有一个按向量搜索的选项,即similar_by_vector

        然而,它实现了蛮力线性搜索,即计算给定向量和词汇表中所有单词的向量之间的余弦相似度,并给出最上面的邻居。如另一个answer 所述,另一种选择是使用近似最近邻搜索算法,如 FLANN。

        分享一个相同的要点: https://gist.github.com/kampta/139f710ca91ed5fabaf9e6616d2c762b

        【讨论】:

          猜你喜欢
          • 2018-11-27
          • 2021-06-26
          • 2018-08-18
          • 1970-01-01
          • 2019-10-15
          • 2019-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多