Python 互信息的香农熵
我有一些关于某些属性的统计数据,如:Python 互信息的香农熵,python,math,entropy,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).
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)=函数(p1,p2)
不是每一个输入行都得到每一个
pK
,所以len(pK)我假设您想要计算每个p1
和每个p2
,p3
,。。。后来
1) 用以下公式计算p1的熵H(X)
:
每个x
都是p1
的后续元素
2) 用相同的方程式计算H(Y)
作为pK
的熵,每个x
都是p1
3) 从p1
和pK
中创建一个新的配对集合:
pairs = zip(p1, pK)
请注意,如果数据列中的值具有不同的含义,则可能应该填充缺少的数据(例如使用0
s或上一次迭代中的值)
4) 使用以下公式计算关节熵H(X,Y)
:
请注意,您不能仅使用第一个等式并将每一对视为单个元素-您必须迭代该等式中p1
和pK
之间的整个笛卡尔积,使用对
集合计算概率。因此,要迭代整个笛卡尔积,请在itertools.product(p1,pK)中对xy使用:…
5) 然后您可以将p1
和pK
之间的互信息设置为:
使用numpy功能,您可以计算关节熵,如下所示:
其中如果p>0
与:
对于某些i,在p(xi)=0的情况下,相应的和0 logb(0)的值被取为0
如果您不想使用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])
从维基百科文章的正式定义一节中取公式。他们称之为信息增益,但与互信息相同。为了计算包含在这个公式中的样本的熵,从维基百科文章的定义部分取公式
所以,你首先计算整个数据集的熵,然后从中减去熵,当你知道所讨论的心房安非他命的值时,剩下的熵
多维直方图可以在Python中使用numpy.historogramdd()
计算哪两个量之间的互信息?主要目标是通过从列表中删除低信息属性来增加F=p1/p2(如果p2=0:F=F0)。那么它是关于pK和p1(p2)的吗@康斯坦丁我还不清楚。您有一组N
样本,每个样本由9个元素/属性组成。您正在计算每个属性的熵。好的现在你要计算互信息。在什么和什么之间???@Konstantin其I(p0,pK)
对于每个pK
,结果是否与上述方法相同?好的,那么您的主要问题是您不知道所有样本的所有属性。当计算p0和pk之间的互信息时,只使用那些包含pk的样本。那么我每次都应该使用不同的p0
,并且它们总是相同的长度。这听起来是合法的。美好的但似乎我需要记录一半的工作才能知道p0
中的样本包含pk
。但无论如何,谢谢。为什么不一样呢?我知道p0是p1和p2的函数,它们总是存在的,对吗?当计算p0和pk之间的MI时,您不需要其他属性,因此您的计算将始终基于两个向量,p0和pk。正如我所理解的:对于联合熵,我应该只考虑受pk影响的p0元素,因此len(pk)=len(p0'),其中p0'是p0的子数组
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)
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])