Optimale Methode zur Berechnung paarweiser gegenseitiger Informationen mit numpy
Für einm x n Matrix, was ist der optimale (schnellste) Weg, um die gegenseitigen Informationen für alle Spaltenpaare zu berechnen (n x n)?
Durchgegenseitige Information, Ich meine:
I (X, Y) = H (X) + H (Y) - H (X, Y)
woherH (X) bezieht sich auf die Shannon-Entropie vonX.
Derzeit benutze ichnp.histogram2d
undnp.histogram
das Gelenk berechnen(X, Y) und individuell(X oder Y) zählt. Für eine gegebene MatrixA
(z. B. eine Matrix von 250000 x 1000 Floats), mache ich eine verschachteltefor
Schleife,
n = A.shape[1]
for ix = arange(n)
for jx = arange(ix+1,n):
matMI[ix,jx]= calc_MI(A[:,ix],A[:,jx])
Sicher muss es dafür bessere / schnellere Wege geben?
Abgesehen davon habe ich auch nach Zuordnungsfunktionen für Spalten (spaltenweise oder zeilenweise Operationen) in Arrays gesucht, aber noch keine gute allgemeine Antwort gefunden.
Hier ist meine vollständige Implementierung gemäß den Konventionen indie Wiki-Seite:
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)
Obwohl meine Arbeitsversion verschachtelt istfor
loops macht das mit vernünftiger Geschwindigkeit, ich würde gerne wissen, ob es einen optimaleren Weg gibt, sich zu bewerbencalc_MI
auf allen Spalten vonA
(um ihre paarweise gegenseitige Information zu berechnen)?
Ich würde auch gerne wissen:
Gibt es effiziente Möglichkeiten zum Zuordnen von Funktionen, um Spalten (oder Zeilen) von zu bearbeiten?np.arrays
(vielleicht magnp.vectorize
, der eher wie ein Dekorateur aussieht)?
Gibt es andere optimale Implementierungen für diese spezifische Berechnung (gegenseitige Information)?