新手求教:Cosine Similarity、PMI与PCA的关联及词相似度项目建议
跨世纪词相似度测算项目问题解答
1. Cosine Similarity与PMI的关联
- PMI(点互信息)是量化两个词之间统计关联性的指标,公式为:
PMI(x,y) = log2(P(x,y)/(P(x)*P(y))),它衡量的是“x和y一起出现的概率”相对于“x、y独立出现概率乘积”的倍数,值越高说明两个词的共现越不是随机事件,语义关联越强。 - Cosine Similarity是衡量两个向量方向相似度的指标,它通过计算向量夹角的余弦值来判断向量的语义趋近程度,只关注向量的方向,不关心绝对值大小。
- 两者的核心关联:PMI通常用来对原始共现矩阵做预处理,把单纯的共现计数转换成带语义权重的矩阵——过滤掉随机共现的噪声,强化有意义的语义关联;之后基于这个PMI矩阵生成的词向量,再用Cosine来计算向量间的语义相似度,相当于PMI给向量“赋能”了统计层面的语义关联,Cosine则负责量化这种关联的相似程度。
2. PCA如何融入你的项目流程
PCA(主成分分析)在这里的作用是降维去冗余:
- 你构建的PMI语义空间(步骤5)是高维的(每个共现词就是一个维度),里面可能存在大量冗余信息(比如多个共现词表达的语义高度重叠)。
- 对这个子空间应用PCA(步骤6),可以把高维的PMI向量压缩到低维的主成分空间里,保留数据中最核心的语义方差,同时去掉噪声和冗余维度。这样处理后,计算Cosine Similarity时,结果会更聚焦于核心语义关联,还能提升计算效率。
- 举个具体的例子:如果你的子空间有100个共现词维度,PCA可以把它压缩到20个主成分维度,既保留了95%以上的语义信息,又简化了后续的相似度计算。
3. 是否应基于PMI矩阵计算Cosine Similarity
非常推荐这么做,原因如下:
- 原始共现矩阵的计数只反映词的共现频率,会被高频无意义词(比如“的”“了”这类停用词)主导,这些词的共现次数多但没有实际语义关联。
- PMI矩阵通过互信息计算,会压低这类随机共现的权重(甚至给出负值),同时放大真正有语义关联的词对的权重,让生成的词向量更贴合实际的语义关系。
- 基于PMI矩阵计算Cosine Similarity,得到的相似度结果是语义层面的相似性,而不是单纯的统计共现频率的相似性,更符合你“词相似度测算”的核心目标。
4. 基准教程与脚本推荐
基础实现思路
- PMI矩阵构建:用Numpy手动实现,步骤大概是:
- 统计每个词的边缘出现次数、词对的共现次数;
- 计算联合概率
P(x,y)和边缘概率P(x)、P(y); - 按PMI公式计算,注意给零概率的情况加平滑项(比如拉普拉斯平滑,避免log(0)报错)。
- PCA与Cosine计算:用Scikit-learn的工具类快速实现:
- 用
sklearn.decomposition.PCA做降维,设置n_components参数指定保留的主成分数量; - 用
sklearn.metrics.pairwise.cosine_similarity直接计算向量间的相似度。
- 用
- 参考逻辑:可以参考GloVe模型的核心预处理思路(GloVe就是基于PMI和加权最小二乘训练词向量),重点学习它对共现矩阵的PMI转换和权重调整方式;另外,手动实现词嵌入的基础教程中,关于共现矩阵、PMI、降维的环节都可以参考。
小优化建议
- 步骤3对比PMI得分时,建议过滤掉PMI值为负的词对(负PMI说明词对共现比随机情况少,无语义关联);
- 步骤5构建语义空间时,可以只保留PMI值高于阈值的共现词,进一步压缩空间,提升后续PCA和相似度计算的效率。
内容的提问来源于stack exchange,提问作者sparxy
相关产品推荐
相关产品推荐

