Liczba pojemników podczas obliczania wzajemnych informacji

10

Chcę kwantyfikować związek między dwiema zmiennymi, A i B, wykorzystując wzajemne informacje. Można to obliczyć, dzieląc obserwacje (patrz przykładowy kod Python poniżej). Jednak jakie czynniki determinują, jaka liczba pojemników jest rozsądna? Potrzebuję szybkiego obliczenia, więc nie mogę po prostu użyć wielu pojemników, aby zachować bezpieczeństwo.

from sklearn.metrics import mutual_info_score

def calc_MI(x, y, bins):
    c_xy = np.histogram2d(x, y, bins)[0]
    mi = mutual_info_score(None, None, contingency=c_xy)
    return mi
pir
źródło

Odpowiedzi:

15

Nie ma najlepszej liczby pojemników do oszacowania wzajemnej informacji (MI) z histogramami. Najlepszym sposobem jest wybranie go za pomocą weryfikacji krzyżowej, jeśli możesz, lub poleganie na zasadzie ogólnej. Z tego powodu zaproponowano wiele innych estymatorów MI, które nie są oparte na histogramach.

Liczba pojemników będzie zależeć od całkowitej liczby punktów danych . Powinieneś starać się unikać zbyt wielu pojemników, aby uniknąć błędów oszacowania dla wspólnego rozkładu między dwiema zmiennymi. Powinieneś także unikać zbyt małej liczby pojemników, aby móc uchwycić związek między dwiema zmiennymi. Biorąc pod uwagę, że generuje histogram 2D ​​z pojemnikami o równej szerokości dla obu i osobiście wybrałbym: W tym przypadku średnio dla dwóch równomiernie rozmieszczonych zmiennych losowych będziesz miał co najmniej punktów dla każda komórka histogramu: nnp.histogram2d(x, y, D)Dxy

re=n/5
5
nreXreY5nre2)5re2)n/5re=n/5
Jest to jeden z możliwych wybór, który symuluje podejście adaptacyjnego podziału zaproponowane w (Cellucci, 2005) . To drugie podejście jest często stosowane do oszacowania MI w celu wnioskowania o sieci genetyczne: np. W MIDER .

Jeśli masz dużo punktów danych i nie ma brakujących wartości, nie powinieneś zbytnio przejmować się znalezieniem najlepszej liczby pojemników; np. jeśli . Jeśli tak nie jest, możesz rozważyć skorygowanie MI dla skończonych próbek. (Steuer i in., 2002) omawia pewną korektę MI dla zadania wnioskowania sieci genetycznej.nn=100,000


Szacowanie liczby przedziałów dla histogramu to stary problem. Być może zainteresuje Cię rozmowa Lauritza Dieckmana na temat oszacowania liczby pojemników na MI. Ta rozmowa oparta jest na jednym z rozdziałów książki Mike'a X Cohena na temat neuronowych szeregów czasowych.

Możesz wybrać i niezależnie i użyć reguły stosowanej do oszacowania liczby przedziałów w histogramach 1D.reXreY

Reguła Freedmana-Diaconisa (brak założenia co do dystrybucji): gdzie to różnica między 75-kwantylem a 25-kwantylem. Spójrz na to powiązane pytanie w SE .

reX=maxX-minX2)IQRn-1/3)
IQR

Reguła Scotta (założenie normalności): gdzie jest odchyleniem standardowym dla .

reX=maxX-minX3.5sXn-1/3)
sXX

Reguła Sturgesa (może nie doceniać liczby pojemników, ale jest dobra dla dużych ): n

reX=1+log2)n

Trudno jest poprawnie oszacować MI za pomocą histogramów. Następnie możesz wybrać inny estymator:

  • Estymator NN Kraskowa , który jest nieco mniej wrażliwy na wybór parametru: lub najbliższych sąsiadów jest często używany jako domyślny. Papier: (Kraskov, 2003)kk=4k=6
  • Oszacowanie MI za pomocą jąder (Moon, 1995) .

Istnieje wiele pakietów do oszacowania MI:

  • Nieparametryczny zestaw narzędzi do szacowania entropii dla Pythona. strona .
  • Zestaw narzędzi do dynamiki informacji w Javie, ale dostępny również dla Pythona. strona .
  • Przybornik ITE w Matlabie. strona .
Simone
źródło
1

Wolę minepyuzyskać i oszacować wzajemne informacje w pythonie.

Możesz zobaczyć szczegóły implementacji pakietu tutaj i przykładowy kod tutaj . Dla łatwiejszego odniesienia kopiuję przykład i wklejam go tutaj:

import numpy as np
from minepy import MINE

def print_stats(mine):
    print "MIC", mine.mic()
    print "MAS", mine.mas()
    print "MEV", mine.mev()
    print "MCN (eps=0)", mine.mcn(0)
    print "MCN (eps=1-MIC)", mine.mcn_general()

x = np.linspace(0, 1, 1000)
y = np.sin(10 * np.pi * x) + x
mine = MINE(alpha=0.6, c=15)
mine.compute_score(x, y)

print "Without noise:"
print_stats(mine)
print

np.random.seed(0)
y +=np.random.uniform(-1, 1, x.shape[0]) # add some noise
mine.compute_score(x, y)

print "With noise:"
print_stats(mine)

Co daje to jako wynik:

Without noise:
MIC 1.0
MAS 0.726071574374
MEV 1.0
MCN (eps=0) 4.58496250072
MCN (eps=1-MIC) 4.58496250072

With noise:
MIC 0.505716693417
MAS 0.365399904262
MEV 0.505716693417
MCN (eps=0) 5.95419631039
MCN (eps=1-MIC) 3.80735492206

Z mojego doświadczenia wynika, że ​​wyniki są wrażliwe alpha, a wartość domyślna .6jest rozsądna. Jednak moje rzeczywiste dane alpha=.3są znacznie szybsze, a szacowane wzajemne informacje mają naprawdę wysoką korelację z tym przypadkiem alpha=.6. Więc jeśli używasz MI, aby wybrać te o wysokim MI, możesz po prostu użyć mniejszego alphai użyć najwyższych wartości jako zamiennika z dobrą dokładnością.

adrin
źródło
Dzięki! Czy porównałeś minepy ze sklearn do oszacowania MI?
pir
Nie, nie mam. Nie jestem pewien, dlaczego nie!
adrin
Właśnie dokonałem porównania sklearn i minepy (zarówno alfa = 0,3, jak i alfa = 0,6). Wyniki są bardzo różne! Ponieważ jest to tak łatwe, prawdopodobnie powinieneś również sprawdzić swoje wyniki przy użyciu obu bibliotek :)
pir
2
MIC nie jest równy wzajemnej informacji (MI). To dwie zupełnie różne rzeczy.
Simone,
1
Tak, oczywiście. W oryginalnym artykule MIC istnieje wiele porównań MI i MIC: uvm.edu/~cdanfort/csc-reading-group/… Program MIC do tego, że można go wykorzystać jako wskaźnik ilości hałasu dla relacji funkcjonalnej - właściwość, która nazywa się „równością” w oryginalnej pracy. Niemniej jednak MI jest nadal bardzo dobrą miarą zależności dla wielu zadań: np. Wyboru cech lub wnioskowania o sieci genetycznej. Oszacowanie jest również szybsze niż MIC.
Simone,