技术问询:基于文档词频计算pool与duck的术语关联度示例
嘿,我来帮你把这个问题拆解得明明白白的——先给你pool和duck的四个相似度指标计算示例,再帮你理清之前两种计算方式的问题所在。
首先先明确我们的基础数据(来自你提供的表格):
| 术语 | D1频次 | D2频次 | 总频次 | 出现文档数 |
|---|---|---|---|---|
| pool | 0 | 23 | 23 | 1(仅D2) |
| duck | 23 | 10 | 33 | 2(D1+D2) |
| 文档总数 | - | - | - | 2 |
核心概念澄清
你之前的困惑主要来自文档级共现和词频级共现的区别:
- 文档级共现:指两个术语同时出现在同一文档的文档数量(这里
pool和duck仅在D2共现,所以共现文档数=1) - 词频级共现:指两个术语在同一文档中的频次关联,通常通过向量运算直接计算,不需要单独统计“共现频次”
1. Pearson相关系数(Pearson Correlation)
Pearson衡量两个术语频次的线性相关程度,把每个文档作为一个样本,术语在文档中的频次作为变量值,计算两个向量的线性相关性。
计算公式
r = (nΣxy - ΣxΣy) / sqrt[(nΣx² - (Σx)²)(nΣy² - (Σy)²)]
其中:
n:文档总数x:pool的文档频次向量[0, 23]y:duck的文档频次向量[23, 10]
代入计算
n = 2Σx = 0 + 23 = 23,Σy = 23 + 10 = 33Σxy = (0*23) + (23*10) = 230Σx² = 0² + 23² = 529,Σy² = 23² + 10² = 629
分子:2*230 - 23*33 = 460 - 759 = -299
分母:sqrt[(2*529 - 23²)(2*629 - 33²)] = sqrt[(1058-529)(1258-1089)] = sqrt[529*169] = 23*13 = 299
最终结果:r = -299 / 299 = -1
说明:这是完全负线性相关——
pool在D2高频,duck在D1高频,趋势完全相反。
2. Dice相关系数(Dice Correlation)
Dice有两种常见计算方式,分别对应文档级和词频级:
文档级Dice(基于是否出现)
适合粗粒度的术语关联,仅考虑文档是否包含术语:
Dice = 2 * 共现文档数 / (A出现文档数 + B出现文档数)
代入:2*1 / (1+2) = 2/3 ≈ 0.667
词频级Dice(基于频次向量)
考虑术语的具体出现次数,公式为:
Dice = 2 * (x·y) / (||x||² + ||y||²)
其中x·y是向量点积,||x||²是向量的平方和。
代入:
- 点积
x·y = 0*23 +23*10=230 - 平方和
||x||²=529,||y||²=629
结果:2*230/(529+629) = 460/1158 ≈ 0.397
3. 互信息(Mutual Information, MI)
互信息衡量两个术语的共现概率与独立概率的差异,这里我们用文档级二元变量(出现=1,不出现=0)计算,更符合术语关联的场景:
计算公式
MI(A,B) = ΣΣ P(A=a,B=b) * log2(P(A=a,B=b)/(P(A=a)*P(B=b)))
首先构建联合概率表:
| duck出现 | duck不出现 | P(pool) | |
|---|---|---|---|
| pool出现 | 1/2 | 0 | 1/2 |
| pool不出现 | 1/2 | 0 | 1/2 |
| P(duck) | 1 | 0 | - |
代入计算
只有两个非零项,且两项的log2(...)均为log2(1)=0,所以:MI(pool,duck) = 0
说明:因为
duck在所有文档中都出现,它的出现无法提供任何关于pool是否出现的信息,所以互信息为0。
4. 期望互信息(Expected Mutual Information, EMI/NMI)
期望互信息是归一化后的互信息,解决互信息受边缘概率影响的问题,通常用**归一化互信息(NMI)**替代,公式为:
NMI(A,B) = MI(A,B) / sqrt(H(A)*H(B))
其中H(X)是术语X的熵:H(X) = -P(X=1)log2(P(X=1)) - P(X=0)log2(P(X=0))
计算熵
H(pool) = -(1/2)log2(1/2) - (1/2)log2(1/2) = 1H(duck) = -1*log2(1) - 0*log2(0) = 0(因为duck总是出现,熵为0)
由于H(duck)=0,这里NMI无法计算。如果我们改用词频级的熵(基于总频次的概率),结果会不同,但在这个数据集下,因为duck的覆盖度是100%,文档级的期望互信息没有意义。
关于你之前的两种计算方式
- 仅考虑文档出现与否的方式:这是文档级的标准计算方式,适合不需要词频权重的粗粒度关联分析,但确实忽略了术语在文档中的重要性(比如
pool在D2的高频),所以合理与否取决于你的分析场景。 - 基于绝对频次的方式:不需要单独计算“共现频次”,而是把每个文档的频次作为向量维度,直接用向量运算(比如Pearson、Dice的词频版)来计算关联度,这才是正确的打开方式——你之前卡壳的“共现频次”其实已经包含在向量的点积或交互项中了。
内容的提问来源于stack exchange,提问作者G. H.

