如何计算N变量的香农熵和互信息

1 投票
2 回答
6562 浏览
提问于 2025-04-18 09:17

我需要计算互信息,所以要先计算N个变量的香农熵。

我写了一段代码来计算某种分布的香农熵。假设我有一个变量x,它是一个数字数组。

根据香农熵的定义,我需要计算概率密度函数的归一化,所以使用numpy.histogram来获取这个值很简单。

import scipy.integrate as scint
from numpy import*
from scipy import*

def shannon_entropy(a, bins):

p,binedg= histogram(a,bins,normed=True)
p=p/len(p)

x=binedg[:-1]
g=-p*log2(p)
g[isnan(g)]=0.

return scint.simps(g,x=x)

只要正确地插入x,并仔细选择箱子的数量,这个函数就能正常工作。

但是这个函数对箱子的数量非常敏感:选择不同的参数值,我得到的结果也不同。

特别是如果我的输入是一个常数值的数组:

x=[0,0,0,....,0,0,0]

这个变量的熵显然应该是0,但如果我选择箱子的数量为1,我得到了正确的答案;如果选择其他值,我却得到了奇怪的(负数)结果。我感觉numpy.histogram有参数normed=True或density=True(正如官方文档所说),它们应该返回归一化的直方图,可能我在从概率密度函数(numpy.histogram的输出)转换到概率质量函数(香农熵的输入)时犯了错误,我这样做:

p,binedg= histogram(a,bins,normed=True)
p=p/len(p)

我想找到解决这些问题的方法,希望能有一个有效的方法来计算香农熵,而不依赖于箱子的数量。

我写了一个函数来计算多个变量的香农熵,但我遇到了同样的错误。代码是这样的,函数shannon_entropydd的输入是一个数组,每个位置上都有要参与统计计算的变量。

def intNd(c,axes):

assert len(c.shape) == len(axes)
assert all([c.shape[i] == axes[i].shape[0] for i in range(len(axes))])
if len(axes) == 1:
    return scint.simps(c,axes[0])
else:
    return intNd(scint.simps(c,axes[-1]),axes[:-1])



def shannon_entropydd(c,bins=30):



hist,ax=histogramdd(c,bins,normed=True)

for i in range(len(ax)):
    ax[i]=ax[i][:-1]

p=-hist*log2(hist)

p[isnan(p)]=0

return intNd(p,ax)

我需要这些量,以便能够计算某些变量之间的互信息

M_info(x,y,z)= H(x)+H(z)+H(y)- H(x,y,z)

其中H(x)是变量x的香农熵。

我必须找到一种方法来计算这些量,所以如果有人有完全不同的代码能正常工作,我可以切换过去,我不需要修复这段代码,只想找到正确的方法来计算这些统计函数!

2 个回答

1

我觉得如果你选择 bins = 1,那么你总是会得到一个熵值为 0,因为在这种情况下,值所在的“桶”没有任何“不确定性”(“不确定性”就是熵所测量的内容)。你应该选择一个“足够大”的桶数,以便能够涵盖你变量可能取的各种值。如果你的值是离散的:对于二进制值,你应该选择 bins >= 2。如果你的变量可以取的值是 {0,1,2},那么你应该选择 bins >= 3,以此类推……

我必须说我没有看你的代码,但这个方法对我有效:

import numpy as np

x = [0,1,1,1,0,0,0,1,1,0,1,1]
bins = 10
cx = np.histogram(x, bins)[0]

def entropy(c):
    c_normalized = c/float(np.sum(c))
    c_normalized = c_normalized[np.nonzero(c_normalized)]
    h = -sum(c_normalized * np.log(c_normalized))  
    return h

hx = entropy(cx)
2

结果会很大程度上依赖于你估计的密度。你能假设一种特定的密度形式吗?如果你避免使用直方图或其他通用的估计方法,比如核密度估计,结果对估计的依赖性会降低。如果你能提供更多关于相关变量的细节,我可以给出更具体的意见。

我在我的论文工作中使用了互信息的估计 [1]。在第8.1节和附录F中有一些关于互信息的内容。

[1] http://riso.sourceforge.net/docs/dodier-dissertation.pdf

撰写回答