对于m x n矩阵,计算所有列对的互信息的最佳(最快)方法是什么(nxn)?
我指的是mutual information:
I(X, Y) = H(X) + H(Y) - H(X,Y)
其中,H(X)是指X的香农熵。
目前我使用np.histogram2d
和np.histogram
计算关节(X,Y)和个体(X或Y)计数。对于给定的矩阵A
(例如250000x 1000个浮点矩阵),我正在做一个嵌套的for
循环
n = A.shape[1]
for ix = arange(n)
for jx = arange(ix+1,n):
matMI[ix,jx]= calc_MI(A[:,ix],A[:,jx])
当然,必须有更好/更快的方法来做到这一点?
另外,我也在数组的列(按列或按行操作)上寻找映射函数,但还没有找到一个好的通用答案。
下面是我的完整实现,遵循the Wiki page中的约定:
import numpy as np
def calc_MI(X,Y,bins):
c_XY = np.histogram2d(X,Y,bins)[0]
c_X = np.histogram(X,bins)[0]
c_Y = np.histogram(Y,bins)[0]
H_X = shan_entropy(c_X)
H_Y = shan_entropy(c_Y)
H_XY = shan_entropy(c_XY)
MI = H_X + H_Y - H_XY
return MI
def shan_entropy(c):
c_normalized = c / float(np.sum(c))
c_normalized = c_normalized[np.nonzero(c_normalized)]
H = -sum(c_normalized* np.log2(c_normalized))
return H
A = np.array([[ 2.0, 140.0, 128.23, -150.5, -5.4 ],
[ 2.4, 153.11, 130.34, -130.1, -9.5 ],
[ 1.2, 156.9, 120.11, -110.45,-1.12 ]])
bins = 5 # ?
n = A.shape[1]
matMI = np.zeros((n, n))
for ix in np.arange(n):
for jx in np.arange(ix+1,n):
matMI[ix,jx] = calc_MI(A[:,ix], A[:,jx], bins)
尽管我的工作版本使用嵌套的for
循环,但它的速度是合理的,我想知道是否有一种更优化的方法来对A
的所有列应用calc_MI
(计算它们的成对互信息)?
我还想知道:
是否有有效的方法将函数映射到np.arrays
的列(或行)上(可能类似于np.vectorize
,看起来更像一个装饰器)?
对于这个特定的计算是否有其他的最佳实现(相互信息)?
我不能建议对n*(n-1)/2上的外环进行更快的计算 向量,但是
calc_MI(x, y, bins)
的实现可以简化 如果您可以使用scipy版本0.13或scikit-learn。在scipy 0.13中,}
此参数控制由函数计算的统计信息。如果
使用
lambda_
参数被添加到^{lambda_="log-likelihood"
(或lambda_=0
),对数似然比 被退回。这也常被称为G或G2统计。除了 系数2*n(其中n是意外事故中的样本总数 表),这是相互的信息。所以你可以实现calc_MI
作为:这与您的实现之间的唯一区别是 实现使用自然对数而不是以2为底的对数 (所以它用“nats”而不是“bits”来表示信息)。如果 你真的更喜欢位,只要把
mi
除以log(2)。如果您有(或可以安装)} ,并将
sklearn
(即scikit learn),则可以使用 ^{calc_MI
实现为:相关问题 更多 >
编程相关推荐