【问题标题】:How to compute the shannon entropy and mutual information of N variables如何计算 N 个变量的香农熵和互信息
【发布时间】:2014-07-31 10:32:51
【问题描述】:

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

我编写了一个代码来计算特定分布的香农熵。 假设我有一个变量 x,数字数组。 按照definition of shannon entropy我需要计算归一化的概率密度函数,所以使用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 (如official documentation中所说)他们应该返回归一化的直方图,并且可能在我从概率密度函数切换的那一刻起出现了一些错误(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)

我需要这些数量才能计算某些变量集之间的mutual information

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

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

我必须找到一种方法来计算这些数量,所以如果有人有一个完全不同类型的代码,我可以打开它,我不需要修复这个代码,而是找到一个正确的方法来计算这个统计数据功能!

【问题讨论】:

    标签: python statistics information-theory


    【解决方案1】:

    结果很大程度上取决于估计的密度。你能假设密度的特定形式吗?如果您避免使用直方图或其他通用估计(例如核密度估计),则可以减少结果对估计的依赖性。如果您能详细说明所涉及的变量,我可以制作更具体的 cmets。

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

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

    【讨论】:

    • 重点就是这样:我不想先验地知道我必须期待哪种分布,我想要一个通用代码来计算变量之间流动的互信息。从理论上讲,我可以拥有一组数据并对其制作直方图,从中我需要推断概率质量函数并从中计算或在该数据集与另一个数据集之间流动的互信息。
    • @user3585292 好的,很公平。但是您为具有未知依赖性的任意变量计算 MI 的问题需要构建它们的联合分布……在您可以做到的范围内,您有一个通用的通用预测算法。我并不是要劝阻你,只是建议你可以期望得到的东西是有限的。也就是说,如果您使用 2 个或(可能)3 个变量,您可能可以通过直方图或其他密度估计(例如核密度)获得可行的结果。
    【解决方案2】:

    我认为,如果您选择 bins = 1,您将始终找到 0 的熵,因为值所在的可能 bin 没有“不确定性”(“不确定性”是熵的衡量标准)。您应该选择一些“足够大”的 bin 来考虑变量可以采用的值的多样性。如果您有离散值:对于二进制值,您应该采用 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2021-12-02
      • 1970-01-01
      相关资源
      最近更新 更多