2014-06-23 4 views
15

Załóżmy mam pewne dane uzyskane empirycznie I:Jak wykonać chi-kwadrat dobroci testu dopasowania za pomocą bibliotek naukowych w Pythonie?

from scipy import stats 
size = 10000 
x = 10 * stats.expon.rvs(size=size) + 0.2 * np.random.uniform(size=size) 

Jest wykładniczo rozproszonych (z niektórych hałas) i chcę, aby to sprawdzić przy użyciu chi-kwadrat dobroci dopasowania (GOF) testu. Jaki jest najprostszy sposób robienia tego przy użyciu standardowych bibliotek naukowych w Pythonie (np. Scipy lub statsmodels) z najmniejszą ilością ręcznych kroków i założeń?

mogę dopasować model z:

param = stats.expon.fit(x) 
plt.hist(x, normed=True, color='white', hatch='/') 
plt.plot(grid, distr.pdf(np.linspace(0, 100, 10000), *param)) 

distribution and empirical data plot

Jest bardzo elegancki obliczyć Kolmogorov-Smirnov test.

>>> stats.kstest(x, lambda x : stats.expon.cdf(x, *param)) 
(0.0061000000000000004, 0.85077099515985011) 

Jednak nie mogę znaleźć dobrego sposobu na obliczenie testu chi-kwadrat.

Istnieje chi-squared GoF function in statsmodel, ale zakłada on dyskretną dystrybucję (a rozkład wykładniczy jest ciągły).

Tylko official scipy.stats tutorial obejmuje tylko przypadek dla niestandardowej dystrybucji i prawdopodobieństwa są budowane przez manipulowanie wieloma wyrażeniami (npoints, npointsh, nbound, normbound), więc nie jest dla mnie jasne, jak to zrobić dla innych dystrybucji. Model chisquare examples zakłada, że ​​oczekiwane wartości i DoF są już uzyskane.

Ponadto, nie szukam sposobu, aby "ręcznie" wykonać test, tak jak było already discussed here, ale chciałbym wiedzieć, jak zastosować jedną z dostępnych funkcji bibliotecznych.

+2

O ile mi wiadomo, nie ma "oficjalnej" funkcji biblioteki pythonowej dla testu chisquare, która obejmuje binning dla ciągłej dystrybucji. Polecam używać Andersona-Darlinga, smes andersa, który powinien mieć lepszą moc, jeśli dobrze pamiętam. – user333700

+0

OK, ale z tego co widzę implementację ['anderson' w SciPy] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.anderson.html#scipy.stats.anderson) obsługuje tylko 5 dystrybucji. – metakermit

+0

Tak, ale anderson obsługuje dystrybucję wykładniczą, której używasz. Jeśli oszacujesz parametry rozkładu i chcesz, aby działał dla każdej dystrybucji, powracasz do binningu dla chisquare lub ładowania kolejnego z testów gof. – user333700

Odpowiedz

3

Przybliżony rozwiązanie dla jednakowych pojemników prawdopodobieństwa:

  • estymacji parametrów rozkładu
  • Korzystanie CDF odwrotny, PPF jeśli jest to scipy.stats.distribution, aby uzyskać binedges dla zwykłego prawdopodobieństwa siatka, np distribution.ppf(np.linspace(0, 1, n_bins + 1), *args)
  • Następnie użycie np.histogram policzyć liczbę obserwacji w każdym pojemniku

następnie użyć chisquare testu na częstotliwościach.

Alternatywą byłoby znalezienie krawędzi bin z percentylów posortowanych danych i użycie cdf do znalezienia rzeczywistych prawdopodobieństw.

Jest to tylko przybliżona, ponieważ teoria dla testu kwadratowego zakłada, że ​​parametry są oszacowane na podstawie prawdopodobieństwa maksymalnego prawdopodobieństwa dla danych kategoryzowanych. I nie jestem pewien, czy wybór zestawów na podstawie danych wpływa na rozkład asymptotyczny.

Nie zajrzałem do tego od dłuższego czasu. Jeśli przybliżone rozwiązanie nie jest wystarczająco dobre, polecam zadać pytanie na temat stats.stackexchange.

+1

Re: czy binning wpłynie na rozkład asymptotyczny, to prawie musi. Może to być jednak nieistotne. Dla binningu i użycia testu chi-kwadrat, będzie to właściwa odpowiedź. +1 – gung

+0

@Gung To zależy od natury aysymptotyki. Wierzę, że jeśli dopasujesz punkty odcięcia w sposób, który pozwala na wzrost minimalnej oczekiwanej liczby binów, rozkład asymptotyczny powinien wynosić chi-kwadrat. Rozkład asymptotyczny jest jednak nieistotny: ważny jest * rzeczywisty * rozkład i jasne jest, że ustalenie punktów odcięcia na podstawie danych wprowadzi dowolne zmiany w tym rozkładzie (jeśli tylko trochę). – whuber

+0

@ user333700 Proszę podać przykład rozwiązania, które podałeś. Próbowałem tego: 'In: np.random.seed (453)', 'W: data_1 = stats.norm.rvs (size = 10000)', 'W: loc, scale = stats.norm.fit (data_1) ',' W: data_2 = stats.norm (loc, scale) .rvs (size = 10000) ',' In: data_1_hist = np.histogram (data_1, bin = 10) ',' W: data_2_hist = np.histogram (data_2, bin = 10) ',' In: print stats.chisquare (data_2_hist [0], data_1_hist [0]) ',' Out: (statystyka = 564.43784612331842, pvalue = 8.926608295951506e-116) '. Również, w jaki sposób należy użyć 'distribution.ppf (np.linspace (0, 1, n_bins + 1), * args)'? – Julia

2

Dlaczego musisz "zweryfikować", czy jest to wykładniczy wykład? Czy na pewno potrzebujesz testu statystycznego? Mogę w zasadzie zagwarantować, że nie jest to ostatecznie wykładniczy test, który byłby znaczący, gdybyś miał wystarczającą ilość danych, sprawiając, że logika używania testu była raczej wymuszona.Może ci pomóc przeczytać ten wątek: Is normality testing 'essentially useless'? lub moja odpowiedź tutaj: Testing for heteroscedasticity with many observations.

Zazwyczaj lepiej jest użyć wykresu qq i/lub pp-plot (w zależności od tego, czy martwisz się o dopasowanie w ogonach czy środku rozkładu, zobacz moją odpowiedź tutaj: PP-plots vs. QQ-plots). Informacje na temat tworzenia qq-działek w Python SciPy można znaleźć w tym wątku SO: Quantile-Quantile plot using SciPy

+0

Nie wiedziałem o knowaniu QQ. Zajrzę do tego, dzięki. Moją motywacją jest po prostu przekazanie pewnej ilościowej miary tego, jak pewna może być dystrybucja zbioru danych (coś bardziej formalnego niż "patrzenie na histogram, wydaje się wykładnicze"). Pomyślałem, że dobroć testów dopasowania może mi w tym pomóc, ale widzę teraz z dyskusji, z którą się łączyłeś, że może nie być to takie proste :) – metakermit

+1

Istnieją sposoby ilościowego określenia, jak blisko są dwie dystrybucje. Statystyczny * test * nie daje ci tego, b/c wartość p jest funkcją zarówno tej odległości, jak i twojego N. Możesz użyć korelacji punktów na wykresie qq lub pp (ale niedźwiedź pamiętając, że r będzie zawsze blisko 1), możesz również użyć czegoś takiego jak [KL] (http://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) (w rzeczywistości nie jest to odległość). Możesz również zadać pytanie na CV o najlepszy sposób uzyskania ilościowej miary dystansu b/t 2. To się okaże skomplikowane i zależy od tego, czego potrzebujesz. – gung

+1

chisquare daje miarę odległości, możesz również wybrać dowolny inny test gofowy jako "miarę odległości". Jednak nie powie ci wiele w skali. Problemy nie są specyficzne dla testów gof. We wszystkich testach hipotezy musisz martwić się zbyt małą mocą w małych próbkach i zbyt dużą mocą w dużych próbkach. Statsmodels ma funkcje do obliczania wielkości efektu i mocy testu chisquare, np. http://statsmodels.sourceforge.net/devel/generated/statsmodels.stats.gof.chisquare_effectsize.html – user333700

Powiązane problemy