基于Gensim Word2Vec模型获取文档-词矩阵及词共现矩阵的方法
Gensim Word2Vec中文档-词矩阵与词-词共现矩阵的获取方法
没问题,咱们一步步来解决你的两个问题:
一、能不能获取文档-词矩阵?
Gensim的Word2Vec模型本身不会直接输出文档-词矩阵,因为它的核心目标是训练词向量,而非统计词频或文档词频。但我们完全可以基于输入语料,结合Word2Vec生成的词汇表来构建这个矩阵,步骤非常清晰:
- 先训练Word2Vec模型,获取和词向量顺序一致的词汇表
- 遍历每个文档,统计每个词的出现次数,用scipy稀疏矩阵存储(大语料下更高效)
下面是针对你给出的语料的完整代码:
import numpy as np from scipy.sparse import csr_matrix from gensim.models import Word2Vec # 你的输入语料 sentences = [['first', 'sentence'], ['second', 'sentence']] # 训练Word2Vec模型(参数可按需调整,这里用最小配置) model = Word2Vec(sentences, min_count=1, vector_size=100) # 获取模型的词汇表,顺序和词向量索引完全对应 vocab = model.wv.index2word # 构建文档-词矩阵的稀疏表示 row_indices = [] col_indices = [] data = [] for doc_idx, doc in enumerate(sentences): # 统计当前文档的词频 word_counts = {} for word in doc: word_counts[word] = word_counts.get(word, 0) + 1 # 将统计结果映射到矩阵的索引位置 for word, count in word_counts.items(): word_idx = vocab.index(word) row_indices.append(doc_idx) col_indices.append(word_idx) data.append(count) # 创建scipy稀疏矩阵 doc_term_matrix = csr_matrix((data, (row_indices, col_indices)), shape=(len(sentences), len(vocab))) # 转换成稠密矩阵查看(小语料适用,大语料不建议) print("文档-词矩阵(可读形式):") print("词汇表:", vocab) print(doc_term_matrix.toarray())
运行后输出的矩阵就是你期望的结果:
[[1 0 1] [0 1 1]]
对应你想要的可读格式:
first second sentence doc0 1 0 1 doc1 0 1 1
二、能不能转换成词-词共现矩阵?
当然可以!词-词共现矩阵的统计逻辑主要有两种:基于文档共现(两个词出现在同一文档就算一次共现)和基于滑动窗口(和Word2Vec训练窗口一致,统计窗口内的词共现)。这里先给你实现你示例中的文档级共现矩阵:
我们可以直接基于上面的文档-词矩阵计算:先把文档-词矩阵转成二进制(词在文档中出现过记为1,否则0),再用矩阵的转置乘以原矩阵,得到的就是词-词共同出现的文档数矩阵。
代码如下:
# 把文档-词矩阵转成二进制矩阵(只记录是否出现,不记录次数) binary_doc_term = doc_term_matrix.sign() # 计算词-词共现矩阵:转置矩阵 × 原矩阵 cooccurrence_matrix = binary_doc_term.T.dot(binary_doc_term) # 查看结果 print("\n词-词共现矩阵(可读形式):") print(cooccurrence_matrix.toarray())
输出结果为:
[[1 0 1] [0 1 1] [1 1 2]]
这个结果和你的示例几乎一致,唯一区别是sentence对应的对角元素是2——因为它在2个文档中都出现了,共现次数(和自己共现的文档数)是2,这是更准确的统计结果。如果你想要对角元素为1,可以手动将对角线置为1,不过一般共现矩阵会保留真实的统计值。
如果需要基于滑动窗口的共现矩阵(和Word2Vec训练时的窗口逻辑一致),可以遍历每个句子的滑动窗口,统计两两词的出现次数,逻辑也很容易实现。
内容的提问来源于stack exchange,提问作者DavidR
相关产品推荐
相关产品推荐

