2014-07-10 11 views
8

Mam pewne problemy wykonawcze funkcji wzajemnego informowania się, że biblioteki uczenia maszynowego Pythona zapewnić w szczególności: sklearn.metrics.mutual_info_score (labels_true, labels_pred, nieprzewidziane = None)Pythona wzajemnego informowania

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

próbuję wdrożyć przykład ja znaleźć w witrynie samouczka Stanford NLP:

example

Witryna znajduje się tutaj: http://nlp.stanford.edu/IR-book/html/htmledition/mutual-information-1.html#mifeatsel2

Problem polega na tym, że wciąż uzyskuję różne wyniki, nie wymyślając jeszcze powodu.

Dostaję koncepcję wzajemnego informowania i wyboru cech, po prostu nie rozumiem, w jaki sposób jest on zaimplementowany w Pythonie. To, co robię, polega na tym, że dostarczam metodę mutual_info_score z dwiema tablicami opartymi na przykładzie strony NLP, ale generuje ona różne wyniki. Innym interesującym faktem jest to, że w każdym razie bawisz się i zmieniasz liczby na tych tablicach, z których najprawdopodobniej uzyskasz taki sam wynik. Czy mam użyć innej struktury danych specyficznej dla Pythona lub jaki jest tego problem? Jeśli ktokolwiek używałby tej funkcji z powodzeniem w przeszłości, byłby mi bardzo pomocny, dziękuję za poświęcony czas.

+1

należy podać nam przykład tego, co dokładnie jest „źle” działa. – lejlot

Odpowiedz

8

Spotkałem ten sam problem już dziś. Po kilku próbach znalazłem prawdziwy powód: log2, jeśli ściśle przestrzegałeś tutorialu NLP, ale sklearn.metrics.mutual_info_score używa logarytmu naturalnego (baza e, numer Eulera). Nie mogę znaleźć tę informację w dokumentacji sklearn ...

I to zweryfikowane przez:

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 

Jeśli to zmienić np.log2 do np.log, myślę, że to daje tę samą odpowiedź jak sklearn. Jedyna różnica polega na tym, że gdy ta metoda zwróci 0, sklearn zwróci liczbę bardzo bliską 0. (I oczywiście użyj sklearn, jeśli nie dbasz o bazę logów, mój fragment kodu jest tylko dla wersji demonstracyjnej, daje słabe wydajność ...)

FYI, 1) pobiera listy, a także np.array; 2) sklearn.metrics.cluster.entropy używa również logu, a nie log2

Edycja: jak w przypadku "tego samego wyniku", nie jestem pewien, co naprawdę masz na myśli. Generalnie wartości w wektorach nie mają znaczenia, liczy się "dystrybucja" wartości. Dbacie o P (X = x), P (Y = y) i P (X = x, Y = y), a nie o wartość x, y.

+1

czy możesz pokazać działający przykład? Mam różne wartości [1,2,2], [1,2,2] jako argumenty dla tego rutynowego i mutual_info_score – user1603472

-2

Poniższy kod należy warunkiem wynik: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) 
Powiązane problemy