对于一个 m x n 矩阵,如何最优(最快)地计算所有列对(n x n)的互信息?
通过 互信息,我的意思是:
目前,我正在使用
肯定有更好/更快速的方法来做这件事吧?
此外,我还在寻找针对数组列(列向或行向操作)的映射函数,但尚未找到一个好的通用答案。
这是我的全部实现,遵循维基页面中的规范:
通过 互信息,我的意思是:
其中,H(X) 是指 X 的香农熵。I(X, Y) = H(X) + H(Y) - H(X,Y)
目前,我正在使用
np.histogram2d
和 np.histogram
来计算联合 (X,Y) 和个体 (X 或 Y) 计数。对于给定的矩阵 A
(例如,一个由浮点数组成的 250000 X 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])
肯定有更好/更快速的方法来做这件事吧?
此外,我还在寻找针对数组列(列向或行向操作)的映射函数,但尚未找到一个好的通用答案。
这是我的全部实现,遵循维基页面中的规范:
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
循环版本可以以合理的速度完成,但我想知道是否有更优化的方法来应用calc_MI
到A
的所有列(计算它们的成对互信息)?
我还想知道:
是否有有效的方法将函数映射到
np.arrays
的列(或行)上进行操作(也许像np.vectorize
这样的装饰器)?是否有其他针对此特定计算(互信息)的最佳实现方式?
calc_MI
和A
的示例输入?让它可以被复制、粘贴和运行。这将极大地帮助任何试图回答你问题的人。 - YXD(n, m)
,则没有简单的方法可以将您想要计算的n * (n - 1) / 2
个唯一值向量化,尽管使用完整笛卡尔积的n * n
个值进行矢量化计算通常更快,即使存在重复值。问题在于,这需要一次性创建所有中间计算对象。使用上述方法,您需要找出一种创建 4D 的 'histogramdd' 的方法... 我不认为它适用于您的大型数据集。我建议探索Cython或C扩展。 - Jaimeshan_entropy
函数中,看起来H = -sum(...)
应该改为H = -np.sum(...)
。 - Warren Weckesser