从 3 个离散变量中寻找条件互信息
Finding conditional mutual information from 3 discrete variable
我正在尝试使用 python 的 pyitlib
包在公式的帮助下找到三个离散随机变量之间的条件互信息:
I(X;Y|Z)=H(X|Z)+H(Y|Z)-H(X,Y|Z)
预期的条件互信息值为= 0.011
我的第一个代码:
import numpy as np
from pyitlib import discrete_random_variable as drv
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.entropy_conditional(X,Z)
##print(a)
b=drv.entropy_conditional(Y,Z)
##print(b)
c=drv.entropy_conditional(X,Y,Z)
##print(c)
p=a+b-c
print(p)
我得到的答案是=0.4632245116328402
我的第二个代码:
import numpy as np
from pyitlib import discrete_random_variable as drv
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.information_mutual_conditional(X,Y,Z)
print(a)
我得到的答案是=0.1583445441575102
而预期结果是=0.011
有人可以帮忙吗?我现在有大麻烦了。任何形式的帮助都将不胜感激。
提前致谢。
根据条件熵的定义,按位计算(即以2为底)得到H(X|Z)=0.784159, H(Y|Z)=0.325011, H(X,Y|Z) = 0.950826。根据您在上面提供的条件互信息的定义,我得到 I(X;Y|Z)=H(X|Z)+H(Y|Z)-H(X,Y|Z)= 0.158344。注意 pyitlib 默认使用基数 2,drv.information_mutual_conditional(X,Y,Z) 似乎在计算正确的结果。
请注意,您在第一个示例中使用 drv.entropy_conditional(X,Y,Z) 来计算条件熵是不正确的,但是您可以使用 drv.entropy_conditional(XY,Z),其中 XY是表示关于 X 和 Y 的联合观察的一维数组,例如 XY = [2*xy[0] + xy[1] for xy in zip(X,Y)].
我认为库函数 entropy_conditional(x,y,z) 有一些错误。我也测试了我的样品,同样的问题发生了。
但是,带有两个变量的函数 entropy_conditional 是可以的。
所以我将 entropy_conditional(x,y,z) 编码为 entropy(x,y,z),结果是正确的.
代码可能不够漂亮
def gen_dict(x):
dict_z = {}
for key in x:
dict_z[key] = dict_z.get(key, 0) + 1
return dict_z
def entropy(x,y,z):
x = np.array([x,y,z]).T
x = x[x[:,-1].argsort()] # sorted by the last column
w = x[:,-3]
y = x[:,-2]
z = x[:,-1]
# dict_w = gen_dict(w)
# dict_y = gen_dict(y)
dict_z = gen_dict(z)
list_z = [dict_z[i] for i in set(z)]
p_z = np.array(list_z)/sum(list_z)
pos = 0
ent = 0
for i in range(len(list_z)):
w = x[pos:pos+list_z[i],-3]
y = x[pos:pos+list_z[i],-2]
z = x[pos:pos+list_z[i],-1]
pos += list_z[i]
list_wy = np.zeros((len(set(w)),len(set(y))), dtype = float , order ="C")
list_w = list(set(w))
list_y = list(set(y))
for j in range(len(w)):
pos_w = list_w.index(w[j])
pos_y = list_y.index(y[j])
list_wy[pos_w,pos_y] += 1
#print(pos_w)
#print(pos_y)
list_p = list_wy.flatten()
list_p = np.array([k for k in list_p if k>0]/sum(list_p))
ent_t = 0
for j in list_p:
ent_t += -j * math.log2(j)
#print(ent_t)
ent += p_z[i]* ent_t
return ent
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.entropy_conditional(X,Z)
##print(a)
b=drv.entropy_conditional(Y,Z)
c = entropy(X, Y, Z)
p=a+b-c
print(p)
0.15834454415751043
我正在尝试使用 python 的 pyitlib
包在公式的帮助下找到三个离散随机变量之间的条件互信息:
I(X;Y|Z)=H(X|Z)+H(Y|Z)-H(X,Y|Z)
预期的条件互信息值为= 0.011
我的第一个代码:
import numpy as np
from pyitlib import discrete_random_variable as drv
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.entropy_conditional(X,Z)
##print(a)
b=drv.entropy_conditional(Y,Z)
##print(b)
c=drv.entropy_conditional(X,Y,Z)
##print(c)
p=a+b-c
print(p)
我得到的答案是=0.4632245116328402
我的第二个代码:
import numpy as np
from pyitlib import discrete_random_variable as drv
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.information_mutual_conditional(X,Y,Z)
print(a)
我得到的答案是=0.1583445441575102
而预期结果是=0.011
有人可以帮忙吗?我现在有大麻烦了。任何形式的帮助都将不胜感激。 提前致谢。
根据条件熵的定义,按位计算(即以2为底)得到H(X|Z)=0.784159, H(Y|Z)=0.325011, H(X,Y|Z) = 0.950826。根据您在上面提供的条件互信息的定义,我得到 I(X;Y|Z)=H(X|Z)+H(Y|Z)-H(X,Y|Z)= 0.158344。注意 pyitlib 默认使用基数 2,drv.information_mutual_conditional(X,Y,Z) 似乎在计算正确的结果。
请注意,您在第一个示例中使用 drv.entropy_conditional(X,Y,Z) 来计算条件熵是不正确的,但是您可以使用 drv.entropy_conditional(XY,Z),其中 XY是表示关于 X 和 Y 的联合观察的一维数组,例如 XY = [2*xy[0] + xy[1] for xy in zip(X,Y)].
我认为库函数 entropy_conditional(x,y,z) 有一些错误。我也测试了我的样品,同样的问题发生了。 但是,带有两个变量的函数 entropy_conditional 是可以的。 所以我将 entropy_conditional(x,y,z) 编码为 entropy(x,y,z),结果是正确的. 代码可能不够漂亮
def gen_dict(x):
dict_z = {}
for key in x:
dict_z[key] = dict_z.get(key, 0) + 1
return dict_z
def entropy(x,y,z):
x = np.array([x,y,z]).T
x = x[x[:,-1].argsort()] # sorted by the last column
w = x[:,-3]
y = x[:,-2]
z = x[:,-1]
# dict_w = gen_dict(w)
# dict_y = gen_dict(y)
dict_z = gen_dict(z)
list_z = [dict_z[i] for i in set(z)]
p_z = np.array(list_z)/sum(list_z)
pos = 0
ent = 0
for i in range(len(list_z)):
w = x[pos:pos+list_z[i],-3]
y = x[pos:pos+list_z[i],-2]
z = x[pos:pos+list_z[i],-1]
pos += list_z[i]
list_wy = np.zeros((len(set(w)),len(set(y))), dtype = float , order ="C")
list_w = list(set(w))
list_y = list(set(y))
for j in range(len(w)):
pos_w = list_w.index(w[j])
pos_y = list_y.index(y[j])
list_wy[pos_w,pos_y] += 1
#print(pos_w)
#print(pos_y)
list_p = list_wy.flatten()
list_p = np.array([k for k in list_p if k>0]/sum(list_p))
ent_t = 0
for j in list_p:
ent_t += -j * math.log2(j)
#print(ent_t)
ent += p_z[i]* ent_t
return ent
X=[0,1,1,0,1,0,1,0,0,1,0,0]
Y=[0,1,1,0,0,0,1,0,0,1,1,0]
Z=[1,0,0,1,1,0,0,1,1,0,0,1]
a=drv.entropy_conditional(X,Z)
##print(a)
b=drv.entropy_conditional(Y,Z)
c = entropy(X, Y, Z)
p=a+b-c
print(p)
0.15834454415751043