相互信息:列联表样式中的计算示例(Java)

时间:2014-12-17 09:57:43

标签: java associations frequency corpus

我使用逐点互信息(PMI)关联度量来计算通过使用从大型语料库中获得的词频来共词的频率。

我正在通过

的经典公式计算PMI
log(P(X,Y) / (P(X)*P(Y))

并使用我在http://collocations.de/AM/index.html上找到的联合和边际频率的列联表表示法

我得到的结果非常相似,但不一样。据我所知,两种方法都应该产生完全相同的结果值。 我做了一个Java-programm(最小工作示例),它使用两个公式使用语料库中的词频。我对这两种方法得到了不同的结果。有人知道为什么吗?

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));
    }

}

1 个答案:

答案 0 :(得分:1)

让我们用相同的术语写下

   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);

我希望这些不同,因为它们在数学上并不相同。

我建议你先写下你想要的数学,然后找到最有效的编码方法。