Python 用numpy计算两两互信息的最佳方法
对于m x n矩阵,计算所有列对(n x n)的互信息的最佳(最快)方法是什么 我的意思是: I(X,Y)=H(X)+H(Y)-H(X,Y) 其中H(X)指X的香农熵 目前我正在使用Python 用numpy计算两两互信息的最佳方法,python,performance,numpy,scipy,information-theory,Python,Performance,Numpy,Scipy,Information Theory,对于m x n矩阵,计算所有列对(n x n)的互信息的最佳(最快)方法是什么 我的意思是: I(X,Y)=H(X)+H(Y)-H(X,Y) 其中H(X)指X的香农熵 目前我正在使用np.histogram2d和np.histogram来计算关节(X,Y)和个体(X或Y)计数。对于给定的矩阵a(例如250000 X 1000个浮点矩阵),我正在为循环执行嵌套 n = A.shape[1] for ix = arange(n) for jx = arange(i
np.histogram2d
和np.histogram
来计算关节(X,Y)和个体(X或Y)计数。对于给定的矩阵a
(例如250000 X 1000个浮点矩阵),我正在为循环执行嵌套
n = A.shape[1]
for ix = arange(n)
for jx = arange(ix+1,n):
matMI[ix,jx]= calc_MI(A[:,ix],A[:,jx])
肯定有更好/更快的方法来做到这一点
顺便说一句,我还寻找了数组上的列映射函数(列操作或行操作),但还没有找到一个好的通用答案
以下是我的完整实施,遵循中的约定:
尽管我的工作版本使用嵌套的for
循环以合理的速度运行,但我想知道是否有更理想的方法将calc\u MI
应用于a
的所有列(以计算它们的成对互信息)
我还想知道:
是否有有效的方法将函数映射到np.array
的列(或行)(可能类似于np.vectorize
,它看起来更像一个装饰器)
是否有其他针对该特定计算的最佳实现(互信息)
我不能建议对n*(n-1)/2上的外环进行更快的计算
向量,但可以简化计算MI(x,y,bin)
的实现
如果可以使用scipy版本0.13或
在scipy 0.13中,向
此参数控制函数计算的统计信息。如果
使用对数似然比
他回来了。这也通常被称为G或G2统计。除了
2*n的系数(其中n是偶然事件中的样本总数
表),这是相互信息。因此您可以实现calc\u MI
作为:
这与您的实现之间的唯一区别是
实现使用自然对数而不是以2为底的对数
(因此它用“nats”而不是“bits”来表示信息)。如果
您确实更喜欢位,只需将mi
除以log(2)
如果您有(或可以安装)sklearn
(即scikit-learn),您可以使用
,并将calc_MI
实现为:
from sklearn.metrics import mutual_info_score
def calc_MI(x, y, bins):
c_xy = np.histogram2d(x, y, bins)[0]
mi = mutual_info_score(None, None, contingency=c_xy)
return mi
您能否将示例代码扩展为包含calc\u MI
和A
的示例输入?这样我们就可以复制、粘贴和运行。将极大地帮助任何试图回答您的问题的人。请阅读此内容并更新您的示例代码,以包括calc_MI
和A
的示例输入。我之前的评论是无意中输入的,而我本想回应此建议。感谢指向sscce.org的指针。对于您当前的方法,这是一个准确的自包含示例吗。如果矩阵的大小为(n,m)
,则没有简单的方法可以仅对所需的n*(n-1)/2
唯一值进行向量化计算,尽管在完全笛卡尔积中对n*n
值进行向量化计算通常更快,即使是重复的。问题在于,它需要一次创建所有中间计算对象。使用上述方法,您必须找到一种创建4D历史图的方法。。。我看不出你庞大的数据集能解决这个问题。我会研究Cython或C扩展…很好的代码!垃圾箱数量的合理默认值是多少?@felbo这是个好问题,不是一个容易回答的问题。你可能会得到一些想法,如果你问它在这个方法不工作,如果一些计数等于零。你为什么建议这种方法超过密度估计?此外,我对你的答案投了赞成票,因为它确实提供了一种有效的方法来计算某些情况下的MI。“你为什么建议这种方法超过密度估计?”我没有。我只建议了问题中给出的代码的两种替代实现。建议的两种方法因连续性校正而不同。更改为chi2\u意外事件(correction=False)
将删除此不一致性。
from scipy.stats import chi2_contingency
def calc_MI(x, y, bins):
c_xy = np.histogram2d(x, y, bins)[0]
g, p, dof, expected = chi2_contingency(c_xy, lambda_="log-likelihood")
mi = 0.5 * g / c_xy.sum()
return mi
from sklearn.metrics import mutual_info_score
def calc_MI(x, y, bins):
c_xy = np.histogram2d(x, y, bins)[0]
mi = mutual_info_score(None, None, contingency=c_xy)
return mi