如何用Gensim的LSI模型计算两句子降维后的余弦相似度
LSI向量余弦相似度实现方案
你写的前置代码已经完成了词典构建、LSI模型训练、句子向量转换的全流程,只差最后一步相似度计算。注意Gensim输出的LSI向量是(主题ID, 主题权重)格式的稀疏元组列表,不需要额外做复杂格式转换就能直接计算,两种常用实现方式如下:
方法1:调用Gensim内置余弦函数(推荐,代码量最少)
Gensim的matutils模块自带适配稀疏向量格式的余弦计算函数,直接传入两个LSI向量就能得到结果,输出值范围为[-1,1],数值越接近1代表两个句子语义相似度越高:
from gensim.matutils import cossim sim_score = cossim(vec_lsi_1, vec_lsi_2) print(sim_score)
方法2:转numpy稠密数组计算(适合需要自定义向量操作的场景)
如果后续需要对LSI向量做其他数值运算,可以先把稀疏向量转成和你设置的主题数等长的稠密数组,再按余弦公式手动计算:
import numpy as np def sparse_to_dense(sparse_vec, total_topics): dense = np.zeros(total_topics) for topic_id, weight in sparse_vec: dense[topic_id] = weight return dense # 训练LSI时你设置的num_topics=400,这里传入对应长度 vec1_dense = sparse_to_dense(vec_lsi_1, 400) vec2_dense = sparse_to_dense(vec_lsi_2, 400) # 余弦相似度公式:点积 / 两个向量模长的乘积 sim_score = np.dot(vec1_dense, vec2_dense) / (np.linalg.norm(vec1_dense) * np.linalg.norm(vec2_dense)) print(sim_score)
额外优化提示
你现在处理输入句子时直接用split()分词,会把标点和单词粘在一起(比如第二个句子里的trawler,会被当成独立token,大概率不在你构建的词典里,会被直接忽略),也没有过滤无意义的停用词,会一定程度影响相似度计算的准确性,建议预处理阶段加上标点清理、停用词过滤的步骤,结果会更贴合实际语义。
内容的提问来源于stack exchange,提问作者Anders
相关产品推荐
相关产品推荐

