如何计算N变量的香农熵和互信息
我需要计算互信息,所以要先计算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 个回答
我觉得如果你选择 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)
结果会很大程度上依赖于你估计的密度。你能假设一种特定的密度形式吗?如果你避免使用直方图或其他通用的估计方法,比如核密度估计,结果对估计的依赖性会降低。如果你能提供更多关于相关变量的细节,我可以给出更具体的意见。
我在我的论文工作中使用了互信息的估计 [1]。在第8.1节和附录F中有一些关于互信息的内容。
[1] http://riso.sourceforge.net/docs/dodier-dissertation.pdf