香农熵互信息

时间:2013-09-16 07:42:51

标签: python math entropy

我对某些属性有一些统计数据:

1st iter : p1:10 p2:0 p3:12 p4:33 p5:0.17 p6:ok p8:133 p9:89
2nd iter : p1:43 p2:1 p6:ok p8:12 p9:33
3rd iter : p1:14 p2:0 p3:33 p5:0.13 p9:2
...

(p1 -> number of tries, p2 -> try done well, p3..pN -> properties of try).

我需要计算每个房产的信息量。 在量化一些程序(例如10级)以使所有输入数字在同一级别之后,输入文件开始看起来像:

p0: 4 3 2 4 5 5 6 7
p3: 4 5 3 3   
p4: 5 3 3 2 1 2 3 
...

p(0) = funct(p1,p2)

并非每个输入行都得到pK所有len(pk) <= len(p0)

现在我知道如何通过每条线的Shannon熵来计算每个属性的熵。我需要从这里计算互信息。

由于长度不同,计算互信息I(p0,pK)的联合熵。

我正在计算这样一个元素的熵:

def entropy(x):
    probs = [np.mean(x == c) for c in set(x)]
    return np.sum(-p * np.log2(p) for p in probs)

因此,对于关节,我需要使用product来生成输入数组x并使用zip(p0,pk)而不是set(x)

2 个答案:

答案 0 :(得分:7)

我假设你想要计算每个p1p2p3,......之间的互信息。

1)将H(X)计算为来自p1的熵:

Equation 1

每个x都是来自p1的后续元素。

2)使用相同的公式计算H(Y)来自pK的熵,每个x是来自p1的后续元素

3)从p1pK创建一个新的对集合:

pairs = zip(p1, pK)

请注意,如果数据列中的值具有不同的含义,那么您应该填充缺失的数据(例如使用0 s或上一次迭代中的值。)

4)使用以下方法计算联合熵H(X,Y)

Equation 2

请注意,您不能只使用第一个等式并将每个对视为一个元素 - 您必须在此等式中迭代p1pK之间的整个笛卡尔积,并使用pairs集合。因此,要迭代整个笛卡尔积,请使用for xy in itertools.product(p1, pK): ...

5)然后,您可以将p1pK之间的互信作为:

Equation 3

使用numpy功能,您可以计算联合熵here

def entropy(X, Y):
    probs = []
    for c1 in set(X):
        for c2 in set(Y):
            probs.append(np.mean(np.logical_and(X == c1, Y == c2)))

    return np.sum(-p * np.log2(p) for p in probs if p > 0)

其中if p > 0entropy's definition一致:

  

对于某些i,对于p(x i )= 0,相应的加数0 log b (0)的值取0 < / p>

如果您不想使用numpy,那么没有它的版本可能如下所示:

def entropyPart(p):
    if not p:
        return 0

    return -p * math.log(p)

def entropy(X, Y):
    pairs = zip(X, Y)
    probs = []
    for pair in itertools.product(X,Y):
        probs.append(1.0 * sum([p == pair for p in pairs]) / len(pairs))

   return sum([entropyPart(p) for p in probs])

答案 1 :(得分:0)

this维基百科文章的形式定义部分获取公式。他们称之为信息增益,但它与互信息相同。为了计算此公式中包含的样本的熵,请从this维基百科文章的定义部分中获取公式。

因此,您首先计算整个数据集的熵,并从中减去当您知道所涉及的属性值时剩下的熵。

可以使用numpy.histogramdd()在Python中计算多维直方图。