Python中文档词向量计算:求和还是取平均?相异矩阵生成疑问
词向量生成文档相异矩阵的方法疑问
我在用词向量生成一批文本文档的相异矩阵时遇到了疑问。当前的做法是:对文本分词,移除未登录词(OOV),将词向量求和得到文档向量,再计算余弦距离生成相异矩阵。想请教这个方法是否正确?另外有人说应该取词向量的平均值,有人说求和就行,哪种方式才对?
当前实现代码
import string import numpy as np from scipy.spatial import distance def preprocess(text): text=text.translate(str.maketrans('', '', string.punctuation)) return [word.lower() for word in text.split()] def get_vector(document,model): words = preprocess(document) word_vectors = [model[word] for word in words if word in model] if not word_vectors: return np.zeros(model.vector_size) return np.sum(np.array(word_vectors), axis=0) def wordembeddingsumcos(documents,model,variant_names): dissimilarity_matrix=np.zeros((len(documents),len(documents))) for i in range(len(documents)): for j in range(i+1,len(documents)): dissimilarity_matrix[i][j]=distance.cosine(get_vector(documents[i],model),get_vector(documents[j],model)) dissimilarity_matrix[j][i]=dissimilarity_matrix[i][j]
方法正确性判断
你的基础流程(分词→去OOV→生成文档向量→计算余弦距离)是合理的,这是词向量生成文档表示的经典“词袋式”思路,核心逻辑没有问题。
求和 vs 平均值的区别
- 求和的特点:
求和得到的文档向量会受文档长度影响——文本越长,包含的有效词越多,向量的模长就越大。但因为你后续计算的是余弦距离(只关注向量方向,不关注模长),求和和平均后的向量在余弦距离计算中结果是完全一致的。因为余弦距离的本质是向量夹角的余弦值,向量缩放(比如除以词数)不会改变夹角大小。 - 平均值的优势:
如果后续需要用到向量的模长信息(比如做基于向量长度的文本相似度判断),平均值会更合理,它消除了文档长度的影响,让不同长度的文本向量具有可比性。但如果只用来计算余弦距离,两种方式没有区别。
代码优化建议
- 可以在
get_vector函数里把求和改成平均,逻辑上更直观,也不影响余弦距离的计算结果:
def get_vector(document,model): words = preprocess(document) word_vectors = [model[word] for word in words if word in model] if not word_vectors: return np.zeros(model.vector_size) return np.mean(np.array(word_vectors), axis=0) # 替换sum为mean
- 计算相异矩阵的双重循环可以用
scipy的工具函数简化,效率更高:
from scipy.spatial.distance import pdist, squareform def wordembeddingsumcos(documents,model,variant_names): doc_vectors = np.array([get_vector(doc, model) for doc in documents]) dissimilarity_matrix = squareform(pdist(doc_vectors, metric='cosine')) return dissimilarity_matrix
内容的提问来源于stack exchange,提问作者D. Zammit
相关产品推荐
相关产品推荐

