2014-07-10 9 views
8

ich einige Probleme habe die gegenseitige Information Funktion implementieren, die Pythons maschinelles Lernen Bibliotheken, insbesondere: sklearn.metrics.mutual_info_score (labels_true, labels_pred, Kontingenz = None)Python-Implementierung von gegenseitiger Information

(http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html)

ich versuche, das Beispiel, das ich in der Stanford NLP Tutorial-Website finden umzusetzen:

example

Die Seite befindet sich hier: http://nlp.stanford.edu/IR-book/html/htmledition/mutual-information-1.html#mifeatsel2

Das Problem ist, dass ich verschiedene Ergebnisse erziele, ohne den Grund dafür herauszufinden.

Ich bekomme das Konzept der gegenseitigen Informationen und Feature-Auswahl, ich verstehe einfach nicht, wie es in Python implementiert ist. Was ich tue, ist, dass ich die wechselseitige_info_score-Methode mit zwei Arrays basierend auf dem NLP-Site-Beispiel zur Verfügung stelle, aber es gibt unterschiedliche Ergebnisse aus. Die andere interessante Tatsache ist, dass Sie sowieso herumspielen und Zahlen auf diesen Arrays ändern, die Sie am wahrscheinlichsten das gleiche Ergebnis erhalten werden. Soll ich eine andere Python-spezifische Datenstruktur verwenden oder was ist das Problem? Wenn jemand diese Funktion in der Vergangenheit erfolgreich genutzt hat, wäre es eine große Hilfe für mich, danke für Ihre Zeit.

+1

Sie uns mit Arbeits Beispiel dafür, was „falsch“ ist genau das bieten sollte. – lejlot

Antwort

8

Ich stieß heute auf das gleiche Problem. Nach ein paar Versuchen habe ich den wahren Grund gefunden: Sie nehmen log2, wenn Sie das NLP-Tutorial genau befolgt haben, aber sklearn.metrics.mutual_info_score verwendet den natürlichen Logarithmus (Basis e, Euler-Zahl). Ich habe nicht dieses Detail in sklearn Dokumentation ...

ich überprüft dies durch:

import numpy as np 
def computeMI(x, y): 
    sum_mi = 0.0 
    x_value_list = np.unique(x) 
    y_value_list = np.unique(y) 
    Px = np.array([ len(x[x==xval])/float(len(x)) for xval in x_value_list ]) #P(x) 
    Py = np.array([ len(y[y==yval])/float(len(y)) for yval in y_value_list ]) #P(y) 
    for i in xrange(len(x_value_list)): 
     if Px[i] ==0.: 
      continue 
     sy = y[x == x_value_list[i]] 
     if len(sy)== 0: 
      continue 
     pxy = np.array([len(sy[sy==yval])/float(len(y)) for yval in y_value_list]) #p(x,y) 
     t = pxy[Py>0.]/Py[Py>0.] /Px[i] # log(P(x,y)/(P(x)*P(y)) 
     sum_mi += sum(pxy[t>0]*np.log2(t[t>0])) # sum (P(x,y)* log(P(x,y)/(P(x)*P(y))) 
    return sum_mi 

Wenn Sie diese np.log2-np.log ändern, ich denke, es würde Ihnen die gleiche Antwort wie sklearn. Der einzige Unterschied ist, dass, wenn diese Methode 0 zurückgibt, sklearn eine Zahl sehr nahe an 0 zurückgibt. (Und natürlich, benutze sklearn, wenn du dich nicht um Log-Base kümmerst, mein Code ist nur für Demo, es gibt schlechte Leistung ...)

FYI, 1) sklearn.metrics.mutual_info_score nimmt Listen sowie np.array; 2) die sklearn.metrics.cluster.entropy verwendet auch log, nicht log2

Edit: wie für "dasselbe Ergebnis", ich bin mir nicht sicher, was Sie wirklich meinen. Im Allgemeinen sind die Werte in den Vektoren nicht wirklich wichtig, es kommt auf die "Verteilung" der Werte an. Sie interessieren sich für P (X = x), P (Y = y) und P (X = x, Y = y), nicht den Wert x, y.

+1

könnten Sie ein laufendes Beispiel zeigen? Ich habe verschiedene Werte auf [1,2,2], [1,2,2] als Argumente für diese Routine und mutual_info_score – user1603472

-2

Der folgende Code sollte zur Verfügung gestellt ein Ergebnis:0.00011053558610110256

c=np.concatenate([np.ones(49), np.zeros(27652), np.ones(141), np.zeros(774106) ]) 
t=np.concatenate([np.ones(49), np.ones(27652), np.zeros(141), np.zeros(774106)]) 

computeMI(c,t) 
Verwandte Themen