WPROWADZENIE : Mam listę ponad 30 000 wartości całkowitych z przedziału od 0 do 47 włącznie, np. [0,0,0,0,..,1,1,1,1,...,2,2,2,2,...,47,47,47,...]
Pobranych z jakiegoś ciągłego rozkładu. Wartości na liście niekoniecznie są w kolejności, ale kolejność nie ma znaczenia dla tego problemu.
PROBLEM : Na podstawie mojego rozkładu chciałbym obliczyć wartość p (prawdopodobieństwo zobaczenia większych wartości) dla dowolnej podanej wartości. Na przykład, jak widać, wartość p dla 0 zbliżałaby się do 1, a wartość p dla wyższych liczb dążyłaby do 0.
Nie wiem, czy mam rację, ale myślę, że aby określić prawdopodobieństwa, muszę dopasować moje dane do teoretycznego rozkładu, który jest najbardziej odpowiedni do opisania moich danych. Zakładam, że do określenia najlepszego modelu potrzebny jest jakiś test dopasowania.
Czy istnieje sposób na zaimplementowanie takiej analizy w Pythonie ( Scipy
lub Numpy
)? Czy mógłbyś przedstawić jakieś przykłady?
Dziękuję Ci!
źródło
Odpowiedzi:
Dopasowanie rozkładu z sumą błędu kwadratowego (SSE)
Jest to aktualizacja i modyfikacja odpowiedzi Saullo , która wykorzystuje pełną listę bieżących
scipy.stats
rozkładów i zwraca rozkład z najmniejszą liczbą SSE między histogramem dystrybucji a histogramem danych.Przykładowe dopasowanie
Korzystając ze zbioru danych El Niño z
statsmodels
, rozkłady są zgodne, a błąd jest określany. Zwracana jest dystrybucja z najmniejszą liczbą błędów.Wszystkie dystrybucje
Dystrybucja najlepszego dopasowania
Przykładowy kod
źródło
density=True
zamiastnormed=True
innp.histogram()
. ^^.plot()
metodach, aby uniknąć nieporozumień w przyszłości. ^^from scipy.stats._continuous_distns import _distn_names
. Następnie możesz użyć czegoś podobnegogetattr(scipy.stats, distname)
do każdegodistname
w _distn_names`. Przydatne, ponieważ dystrybucje są aktualizowane różnymi wersjami SciPy.ax = data.plot(kind='hist', bins=50, normed=True, alpha=0.5, color=list(matplotlib.rcParams['axes.prop_cycle'])[1]['color'])
W SciPy 0.12.0 zaimplementowano 82 funkcje dystrybucji . Możesz sprawdzić, jak niektóre z nich pasują do Twoich danych, używając ich
fit()
metody . Sprawdź poniższy kod, aby uzyskać więcej informacji:Bibliografia:
- Rozkłady dopasowania, dobroć dopasowania, wartość p. Czy można to zrobić w Scipy (Python)?
- Oprawa rozprowadzająca ze Scipy
A tutaj lista z nazwami wszystkich funkcji dystrybucyjnych dostępnych w Scipy 0.12.0 (VI):
źródło
normed = True
kreśląc histogram? Nie pomnożyłbyśpdf_fitted
przezsize
, prawda?from scipy.stats._continuous_distns import _distn_names
. Następnie możesz użyć czegoś podobnegogetattr(scipy.stats, distname)
do każdegodistname
w _distn_names`. Przydatne, ponieważ dystrybucje są aktualizowane różnymi wersjami SciPy.fit()
metoda wspomniana przez @Saullo Castro zapewnia oszacowanie maksymalnego prawdopodobieństwa (MLE). Najlepszy rozkład danych to ten, który daje najwyższy, można określić na kilka różnych sposobów: na przykład1, ten, który daje największe prawdopodobieństwo logowania.
2, ten, który daje najmniejsze wartości AIC, BIC lub BICc (patrz wiki: http://en.wikipedia.org/wiki/Akaike_information_criterion , zasadniczo można go postrzegać jako prawdopodobieństwo dziennika dostosowane do liczby parametrów, jako dystrybucję z większą parametry powinny być lepiej dopasowane)
3, ten, który maksymalizuje późniejsze prawdopodobieństwo bayesowskie. (patrz wiki: http://en.wikipedia.org/wiki/Posterior_probability )
Oczywiście, jeśli masz już rozkład, który powinien opisywać twoje dane (w oparciu o teorie z twojej konkretnej dziedziny) i chcesz się tego trzymać, pominiesz krok identyfikacji najlepiej dopasowanego rozkładu.
scipy
nie zawiera funkcji do obliczania prawdopodobieństwa logów (chociaż zapewniona jest metoda MLE), ale twardy kod jest łatwy: zobacz Czy wbudowane funkcje gęstości prawdopodobieństwa w `scipy.stat.distributions` są wolniejsze niż te podane przez użytkownika?źródło
scipy
AFAICU, twoja dystrybucja jest dyskretna (i tylko dyskretna). Dlatego samo policzenie częstotliwości różnych wartości i ich normalizacja powinno wystarczyć do twoich celów. A więc przykład, aby to zademonstrować:
Zatem prawdopodobieństwo zobaczenia wartości wyższych niż
1
jest po prostu (zgodnie z komplementarną funkcją dystrybucji skumulowanej (ccdf) :Proszę to zanotować ccdf jest ściśle powiązany z funkcją przetrwania (sf) , ale jest również definiowany za pomocą dystrybucji dyskretnych, podczas gdy sf jest definiowany tylko dla ciągłych dystrybucji.
źródło
Brzmi to jak problem z oszacowaniem gęstości prawdopodobieństwa.
Zobacz także http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html .
źródło
Spróbuj
distfit
bibliotekę.pip install distfit
Zauważ, że w tym przypadku wszystkie punkty będą znaczące ze względu na równomierny rozkład. W razie potrzeby możesz filtrować za pomocą dist.y_pred.
źródło
W OpenTURNS użyłbym kryteriów BIC, aby wybrać najlepszą dystrybucję, która pasuje do takich danych. Dzieje się tak, ponieważ kryteria te nie dają zbyt dużej przewagi rozkładom, które mają więcej parametrów. Rzeczywiście, jeśli rozkład ma więcej parametrów, łatwiej jest, aby dopasowany rozkład był bliżej danych. Co więcej, Kołmogorov-Smirnov może nie mieć sensu w tym przypadku, ponieważ mały błąd w zmierzonych wartościach będzie miał ogromny wpływ na wartość p.
Aby zilustrować proces ładuję dane El-Nino, które zawierają 732 miesięczne pomiary temperatury od 1950 do 2010 roku:
Łatwo jest uzyskać 30 wbudowanych jednozmiennych fabryk dystrybucji
GetContinuousUniVariateFactories
metodą statyczną. Po zakończeniuBestModelBIC
metoda statyczna zwraca najlepszy model i odpowiadający mu wynik BIC.który drukuje:
Aby graficznie porównać dopasowanie do histogramu, korzystam z
drawPDF
metod najlepszego rozkładu.To daje:
Więcej szczegółów na ten temat znajduje się w dokumencie BestModelBIC . Byłoby możliwe włączenie dystrybucji Scipy do SciPyDistribution lub nawet z dystrybucjami ChaosPy do ChaosPyDistribution , ale myślę, że obecny skrypt spełnia najbardziej praktyczne cele.
źródło
Wybacz mi, jeśli nie rozumiem Twojej potrzeby, ale co z przechowywaniem danych w słowniku, w którym klucze byłyby liczbami od 0 do 47 i wartościami liczby wystąpień powiązanych z nimi kluczy na Twojej oryginalnej liście?
Zatem Twoje prawdopodobieństwo p (x) będzie sumą wszystkich wartości kluczy większych niż x podzieloną przez 30000.
źródło