我对某些属性有一些统计信息,例如:
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) = funct(p1,p2)
。并非每个输入行都具有
pK
和len(pk) <= len(p0)
。现在,我知道如何通过每条线的香农熵来计算每个属性的熵。我需要从这里计算互信息。
互信息
I(p0,pK)
的联合熵的计算由于长度不同而被卡住了。我正在像这样计算一个元素的熵:
def entropy(x):
probs = [np.mean(x == c) for c in set(x)]
return np.sum(-p * np.log2(p) for p in probs)
因此,对于联合,我需要使用
product
生成输入数组x
并使用zip(p0,pk)
而不是set(x)
? 最佳答案
我假设您要随后计算每个p1
与每个p2
,p3
,...之间的相互信息。
1)使用以下公式从p1计算H(X)
作为熵:
每个x
是p1
的后续元素。
2)用相同的方程从H(Y)
计算pK
作为熵,每个x
是p1
的后续元素
3)根据p1
和pK
创建一个新的对集合:
pairs = zip(p1, pK)
请注意,如果数据列中的值具有不同的含义,则您可能应该填充丢失的数据(例如,使用
0
或上一次迭代的值)。4)使用以下公式计算联合熵
H(X,Y)
:请注意,您不能只使用第一个方程式并将每对视为一个元素-您必须迭代此方程式中
p1
和pK
之间的整个笛卡尔积,并使用pairs
集合计算概率。因此,要遍历整个笛卡尔积,请使用for xy in itertools.product(p1, pK): ...
。5)然后,您可以使
p1
和pK
之间的相互信息如下:使用numpy功能,您可以按照here所示计算联合熵:
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)
其中
if p > 0
与entropy's definition一致:如果您不想使用
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 - 香农对互信息的熵,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18822727/