我正在使用逐点互信息 (PMI) 关联度量,通过使用从大型语料库获得的词频来计算单词同时出现的频率。
我正在通过经典公式计算 PMI
log(P(X,Y) / (P(X)*P(Y))
并使用我在 http://collocations.de/AM/index.html 上找到的联合频率和边际频率的列联表符号。
我得到的结果非常相似,但又不一样。据我了解,两种方法都应该产生完全相同的结果值。 我制作了一个小型 Java 程序(最小工作示例),该程序使用两个公式的语料库中的词频。这两种方法我得到不同的结果。有人知道为什么吗?
public class MutualInformation
{
public static void main(String[] args)
{
long N = 1024908267229L;
// mutual information = log(P(X,Y) / P(X) * P(Y))
double XandY = (double) 1210738 / N;
double X = (double) 67360790 / N;
double Y = (double) 1871676 / N;
System.out.println(Math.log(XandY / (X * Y)) / Math.log(10));
System.out.println("------");
// contingency table notation as on www.collocations.de
long o11 = 1210738;
long o12 = 67360790;
long o21 = 1871676;
long c1 = o11 + o21;
long r1 = o11 + o12;
double e11 = ((double) r1 * c1 / N);
double frac = (double) o11 / e11;
System.out.println(Math.log(frac) / Math.log(10));
}
}
最佳答案
让我们用同样的术语来写
long o11 = 1210738;
long o12 = 67360790;
long o21 = 1871676;
long N = 1024908267229L
第一个方程是
XandY = o11 / N;
X = o12 / N;
Y = o21 / N;
所以
XandY / (X * Y)
是
(o11 / N) / (o12 / N * o21 / N)
或
o11 * N / (o12 * o21)
请注意,没有进行任何添加。
第二个方程相当不同。
c1 = o11 + o21;
r1 = o11 + o12;
e11 = ((double) r1 * c1 / N);
frac = (double) o11 / e11;
所以
e11 = (o11 + o21) * (o11 + o12) /N;
frac = (o11 * N) / (o11^2 + o11 * o12 + o21 * o11 + o21 * o12);
我希望它们会有所不同,因为从数学上讲它们是不一样的。
我建议你先写出你想要的数学内容,然后找到最有效的编码方式。
关于java - 互信息: Calculation example (Java) in contingency table style,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27522830/