我需要计算互信息,因此需要计算 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,并仔细选择此功能起作用的 bin 编号。
但是这个函数非常依赖于 bin 编号:选择这个参数的不同值我得到不同的值。
特别是如果我的输入是一组值常量:
x=[0,0,0,....,0,0,0]
这个变量的熵显然必须为 0,但是如果我选择等于 1 的 bin 编号,我会得到正确的答案,如果我选择不同的值,我会得到奇怪的无意义(否定)答案.. 我的感觉是 numpy .histogram 具有参数 normed=True 或 density= True (如官方文档中所述)它们应该返回归一化的直方图,并且可能在我从概率密度函数切换时出现一些错误(numpy的输出.histogram)到概率质量函数(香农熵的输入),我这样做:
p,binedg= histogram(a,bins,normed=True)
p=p/len(p)
我想找到解决这些问题的方法,我想有一种有效的方法来计算独立于 bin 数的香农熵。
我写了一个函数来计算更多变量分布的香农熵,但我得到了同样的错误。代码是这样的,其中函数 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 的香农熵
我必须找到一种方法来计算这些数量,所以如果有人有一种完全不同的代码,我可以打开它,我不需要修复这个代码,而是找到一个正确的方法来计算这个统计函数!