Próbuję napisać własny kod w języku Python, aby obliczyć statystyki t i p-wartości dla jednego i dwóch niezależnych testów t tailed. Mogę użyć normalnego przybliżenia, ale na razie próbuję po prostu użyć rozkładu t. Nie udało mi się dopasować wyników statystyk biblioteki SciPy do moich danych testowych. Mogłabym użyć świeżej pary oczu, żeby zobaczyć, czy nie robię gdzieś głupiego błędu.Śledzenie założeń wykonanych przez funkcję `ttest_ind()` SciPy
Uwaga, jest to cross-posted from Cross-Validated, ponieważ trwało to przez jakiś czas bez odpowiedzi, więc pomyślałem, że nie zaszkodzi również uzyskać opinie programistów. Próbuję zrozumieć, czy jest jakiś błąd w algorytmie, który używam, który powinien reprodukować wynik SciPy. Jest to prosty algorytm, dlatego zastanawiające jest, dlaczego nie mogę zlokalizować błędu.
Mój kod:
import numpy as np
import scipy.stats as st
def compute_t_stat(pop1,pop2):
num1 = pop1.shape[0]; num2 = pop2.shape[0];
# The formula for t-stat when population variances differ.
t_stat = (np.mean(pop1) - np.mean(pop2))/np.sqrt(np.var(pop1)/num1 + np.var(pop2)/num2)
# ADDED: The Welch-Satterthwaite degrees of freedom.
df = ((np.var(pop1)/num1 + np.var(pop2)/num2)**(2.0))/( (np.var(pop1)/num1)**(2.0)/(num1-1) + (np.var(pop2)/num2)**(2.0)/(num2-1))
# Am I computing this wrong?
# It should just come from the CDF like this, right?
# The extra parameter is the degrees of freedom.
one_tailed_p_value = 1.0 - st.t.cdf(t_stat,df)
two_tailed_p_value = 1.0 - (st.t.cdf(np.abs(t_stat),df) - st.t.cdf(-np.abs(t_stat),df))
# Computing with SciPy's built-ins
# My results don't match theirs.
t_ind, p_ind = st.ttest_ind(pop1, pop2)
return t_stat, one_tailed_p_value, two_tailed_p_value, t_ind, p_ind
Aktualizacja:
Po przeczytaniu nieco więcej na temat testu t-Welch, widziałem, że należy przy użyciu wzoru Welch-Satterthwaitea obliczyć stopnie wolność. Zaktualizowałem powyższy kod, aby to odzwierciedlić.
Z nowymi stopniami swobody, uzyskuję bliższy wynik. Moja dwustronna wartość p jest wyłączona o około 0,008 od wersji SciPy ... ale to nadal jest zbyt duży błąd, więc nadal muszę robić coś niepoprawnego (lub funkcje dystrybucji SciPy są bardzo złe, ale trudno w to uwierzyć są one dokładne z dokładnością do 2 miejsc po przecinku).
Druga aktualizacja:
Kontynuując spróbować rzeczy, pomyślałem, że może wersja scipy automatycznie oblicza Normalny przybliżenie do rozkładu t gdy stopnie swobody są wystarczająco wysokie (około> 30). Ponownie przetestowałem mój kod, wykorzystując dystrybucję Normalną, a obliczone wyniki są w rzeczywistości oddalone od SciPy, niż gdy używam dystrybucji t.
Bonus pytanie :) (Więcej teoria statystyczna związana; krępuj się ignorować)
Ponadto, t-statystyka jest ujemna. Właśnie zastanawiałem się, co to oznacza dla jednostronnego testu t-Studenta. Czy to zwykle oznacza, że powinienem badać w kierunku ujemnym w kierunku testu? W moich danych testowych populacja 1 jest grupą kontrolną, która nie otrzymała określonego programu szkolenia zawodowego. Populacja 2 otrzymała go, a zmierzone dane są różnicami płac przed/po leczeniu.
Mam więc powody, by sądzić, że średnia dla populacji 2 będzie większa. Ale z punktu widzenia teorii statystycznej, nie wydaje się słuszne wymyślanie testu w ten sposób. Jak mógłbym sprawdzić (dla testu jednostronnego) w kierunku ujemnym bez polegania na subiektywnej wiedzy o danych? Czy jest to tylko jedna z tych częstych rzeczy, które, choć nie są filozoficznie rygorystyczne, muszą być wykonywane w praktyce?
Istnieją już funkcje w scipy.stats do obliczenia tego: ttest_ind i ttest_rel –
Proszę ponownie przeczytać moje pytanie. – ely
Istnieją dwa powody. (a) To nie jest ostateczny kod (który będzie w C++), ale chciałem się upewnić, że mój algorytm jest poprawny, zanim napiszę wersję .cpp. Dzięki Boost mogę uzyskać większość wygodnych funkcji CDF i łatwo jest napisać własne kalkulatory średniej i wariancji. Więc pokazując, że działa to na moich danych testowych w Pythonie (o wiele łatwiej niż testowanie w C++, gdzie nie mam konkurencyjnej metody do porównania), daje mi znać, że robię to dobrze, więc mogę iść dalej. – ely