gensim中的词共现矩阵

4
在构建Python Gensim Word2Vec model时,是否有一种方法可以查看文档到词矩阵?
使用输入sentences = [['first', 'sentence'], ['second', 'sentence']],我希望能看到类似以下的内容*:
      first  second  sentence
doc0    1       0        1
doc1    0       1        1

我已经说明了“可读性高”,但我正在寻找一个基于model.wv.index2word索引的scipy(或其他)矩阵。

那么,它能转换成一个单词到单词的矩阵吗(以查看共现关系)?类似于:

          first  second  sentence
first       1       0        1
second      0       1        1  
sentence    1       1        2   

我已经使用CountVectorizer实现了类似词-词共现矩阵的东西。它运行良好。但是,我已经在我的流程中使用gensim,速度/代码简洁对我的用例很重要。

2个回答

2

如果给你一个由单词列表组成的列表作为语料库,你需要做的就是创建一个Gensim字典,将你的语料库转化为词袋模型,然后创建矩阵:

from gensim.matutils import corpus2csc
from gensim.corpora import Dictionary

# somehow create your corpus

dct = Dictionary(corpus)
bow_corpus = [dct.doc2bow(line) for line in corpus]
term_doc_mat = corpus2csc(bow_corpus)

您的term_doc_mat是一个Numpy压缩稀疏矩阵。如果您想要一个术语-术语矩阵,您可以将其乘以其转置,即:

import numpy as np
term_term_mat = np.dot(term_doc_mat, term_doc_mat.T)

谢谢 @Syncrossus!这太好了。我意识到我已经从gensim管道的太下面开始了,你的答案证实了我的想法。结果转换部分变得更加棘手(这是我在发布时没有预料到的)。你的答案适用于我的示例,因为我只有1和0,但不适用于更高的数字。看起来是朝着正确的方向发展。 - DavidR
我尝试查看API,但是我没有找到这个功能...索引保存在哪里?(即每个索引关联的单词是什么) - chase

0

单词到单词的转换比我最初想象的要复杂得多(至少对我来说是这样)。np.dot()是解决方案的关键,但我需要先应用一个掩码。我创建了一个更复杂的示例进行测试...

想象一下一个文档-单词矩阵

#       word1  word2  word3
# doc0    3      4      2
# doc1    6      1      0
# doc3    8      0      4 
  • 在文档中,单词2出现了9次,单词1出现了9次
  • 在文档中,单词2出现了5次,单词2出现了5次
  • 在文档中,单词2出现了2次,单词3出现了2次

因此,当我们完成时,我们应该得到类似于以下内容的内容(或其相反)。按列阅读,单词-单词矩阵变为:

#       word1  word2  word3
# word1  17      9     11
# word2   5      5      4
# word3   6      2      6

np.dot() 直接计算的结果为:

import numpy as np
doc2word = np.array([[3,4,2],[6,1,0],[8,0,4]])
np.dot(doc2word,doc2word.T)
# array([[29, 22, 32],
#        [22, 37, 48],
#        [32, 48, 80]])

这意味着word1与自身出现了29次。

但是,如果我不是将doc2word乘以自身,而是先构建一个掩码,我会更接近目标。然后我需要颠倒参数的顺序:

import numpy as np
doc2word = np.array([[3,4,2],[6,1,0],[8,0,4]])
# a mask where all values greater than 0 are true
# so when this is multiplied by the orig matrix, True = 1 and False = 0
doc2word_mask = doc2word > 0  

np.dot(doc2word.T, doc2word_mask)
# array([[17,  9, 11],
#        [ 5,  5,  4],
#        [ 6,  2,  6]])

我已经想了太久了....


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接