Ótima maneira de calcular informações mútuas emparelhadas usando numpy
Para ummx n matriz, qual é a maneira ideal (mais rápida) de calcular a informação mútua para todos os pares de colunas (n x n)
Porinformação mútua, Quero dizer:
I (X, Y) = H (X) + H (Y) - H (X, Y)
OndeH (X) refere-se à entropia de Shannon deX.
Atualmente estou usandonp.histogram2d
enp.histogram
calcular a articulação(X, Y) e individual(X ou Y) conta. Para uma determinada matrizA
(por exemplo, uma matriz de 250000 X 1000 de flutuadores), eu estou fazendo um aninhadofor
laço
n = A.shape[1]
for ix = arange(n)
for jx = arange(ix+1,n):
matMI[ix,jx]= calc_MI(A[:,ix],A[:,jx])
Certamente deve haver maneiras melhores / mais rápidas de fazer isso?
Como um aparte, eu também procurei funções de mapeamento em colunas (operações de coluna ou linha) em matrizes, mas ainda não encontrei uma boa resposta geral.
Aqui está a minha implementação completa, seguindo as convenções ema página do Wiki:
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)
Embora minha versão de trabalho com aninhadofor
loops faz isso a uma velocidade razoável, eu gostaria de saber se existe uma maneira mais ideal de aplicarcalc_MI
em todas as colunas deA
(para calcular sua informação mútua em pares)?
Eu também gostaria de saber:
Se existem maneiras eficientes de mapear funções para operar em colunas (ou linhas) denp.arrays
(talvez comonp.vectorize
, que mais parece um decorador?
Se existem outras implementações ideais para este cálculo específico (informação mútua)?