基于Doc2Vec的文档词向量余弦相似度计算主题流行度有效性咨询
Doc2Vec时序主题流行度计算异常问题解答
方法有效性与数据规模判断
你采用的通过文档嵌入和主题词嵌入的余弦相似度衡量主题流行度的方法是经过验证的有效方案,不存在原理性问题。25万篇文档、10万+词汇量的训练规模完全满足Doc2Vec的训练要求,数据量不是导致结果异常的原因。
你遗漏的关键环节与代码问题
- 训练参数不足:你当前调用Gensim的Doc2Vec用了默认的5轮训练,对于新闻语料来说训练轮数严重不足,嵌入向量未收敛,结果随机性极强。建议将
epochs参数调整为15~20,且每轮训练前打乱全部文档的顺序,避免文档按时间排序带来的训练偏差。 - 语义漂移问题未处理:你对全时间段语料联合训练嵌入,会导致多义词的语义被全局平均。比如你用到的
corona一词,2020年之前大多指代啤酒品牌、日冕等含义,2020年才和新冠强相关,全局训练的词向量会把两种语义混在一起,自然无法正确识别2020年的新冠相关文档。 - 相似度计算逻辑错误:你当前是对每个主题词分别计算与文档向量的余弦相似度,再取平均值,这种方式容易被离群词向量干扰。正确的做法是先把所有主题词的归一化词向量取平均得到统一的主题向量,再和归一化的文档向量计算余弦相似度。
- 直接使用训练时的文档向量:Gensim Doc2Vec训练过程中生成的
docvecs是训练的副产品,泛化稳定性差。建议训练完成后用d2vmodel.infer_vector()方法重新推断每篇文档的向量,再用于相似度计算。
代码修改参考
你可以调整相似度计算函数的逻辑:
# 修改后的主题流行度计算逻辑 def topicalprevalence(topic, docvecs, wordvecs): # 先计算统一的主题向量 topic_vecs = [nrm(wordvecs[j]) for j in topic if j in wordvecs] if not topic_vecs: raise ValueError("所有主题词均不在词表中") topic_avg_vec = sum(topic_vecs) / len(topic_vecs) topic_avg_vec = nrm(topic_avg_vec) # 逐篇计算与主题向量的余弦相似度 proj_lst = [nrm(docvec) @ topic_avg_vec for docvec in docvecs] topicsyrs = { 'topic': proj_lst, 'year': df['datetime'].dt.year } return pd.DataFrame(topicsyrs)
内容的提问来源于stack exchange,提问作者fritsvegters
相关产品推荐
相关产品推荐

