Załóżmy, że mam dane z dwoma niezależnymi grupami:
g1.lengths <- c (112.64, 97.10, 84.18, 106.96, 98.42, 101.66)
g2.lengths <- c (84.44, 82.10, 83.26, 81.02, 81.86, 86.80,
85.84, 97.08, 79.64, 83.32, 91.04, 85.92,
73.52, 85.58, 97.70, 89.72, 88.92, 103.72,
105.02, 99.48, 89.50, 81.74)
group = rep (c ("g1", "g2"), c (length (g1.lengths), length (g2.lengths)))
lengths = data.frame( lengths = c(g1.lengths, g2.lengths), group)
Oczywiste jest, że wielkość próby na grupę jest tendencyjna, gdy g1 ma 6 obserwacji, a g2 ma 22 . Tradycyjna ANOVA sugeruje, że grupy mają różne środki, gdy wartość krytyczna jest ustawiona na 0,05 (wartość p wynosi 0,0044 ).
summary (aov (lengths~group, data = lengths))
Biorąc pod uwagę, że moim celem jest porównanie średniej różnicy, takie niezrównoważone i małe próbki danych mogą dawać nieodpowiednie wyniki przy tradycyjnym podejściu. Dlatego chcę wykonać test permutacji i bootstrap.
BADANIE UPRAWNIENIA
Hipoteza zerowa (H0) stwierdza, że średnie grupy są takie same. To założenie w teście permutacji jest uzasadnione poprzez połączenie grup w jedną próbkę. Zapewnia to, że próbki dla dwóch grup zostały pobrane z identycznego rozkładu. Poprzez powtarzanie próbkowania (a ściślej - przetasowanie) z zebranych danych, obserwacje są ponownie przydzielane (tasowane) do próbek w nowy sposób i obliczana jest statystyka testu. Wykonanie tego n razy da rozkład próbkowania statystyk testowych przy założeniu, że H0 ma wartość PRAWDA. Na koniec, pod H0, wartość p jest prawdopodobieństwem, że statystyka testu jest równa lub przekracza wartość obserwowaną.
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.p <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.p <- NULL
set.seed (5)
for (i in 1 : iterations) {
resample <- sample (c(1:length (pool)), length(pool))
g1.perm = pool[resample][1 : s.size.g1]
g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
sampl.dist.p[i] = mean (g1.perm) - mean (g2.perm)
}
p.permute <- (sum (abs (sampl.dist.p) >= abs(obs.diff.p)) + 1)/ (iterations+1)
Podana wartość p testu permutacji wynosi 0,0053 . OK, jeśli zrobiłem to poprawnie, permutacje i parametryczna ANOVA dają prawie identyczne wyniki.
BOOTSTRAP
Przede wszystkim mam świadomość, że bootstrap nie może pomóc, gdy próbki są zbyt małe. Ten post pokazał, że może być jeszcze gorzej i wprowadzać w błąd . Po drugie podkreślono, że test permutacji jest ogólnie lepszy niż bootstrap, gdy głównym celem jest testowanie hipotez. Niemniej jednak ten świetny post rozwiązuje ważne różnice między metodami intensywnie korzystającymi z komputera. Jednak tutaj chciałbym postawić (wierzę) inne pytanie.
Najpierw przedstawię najpopularniejsze podejście do ładowania początkowego (Bootstrap1: ponowne próbkowanie w próbce zbiorczej ):
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.b1 <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.b1 <- NULL
set.seed (5)
for (i in 1 : iterations) {
resample <- sample (c(1:length (pool)), length(pool), replace = TRUE)
# "replace = TRUE" is the only difference between bootstrap and permutations
g1.perm = pool[resample][1 : s.size.g1]
g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
sampl.dist.b1[i] = mean (g1.perm) - mean (g2.perm)
}
p.boot1 <- (sum (abs (sampl.dist.b1) >= obs.diff.b1) + 1)/ (iterations+1)
Wartość P wykonywanego w ten sposób ładowania początkowego wynosi 0,005 . Nawet jeśli brzmi to rozsądnie i prawie identycznie jak parametryczna ANOVA i test permutacji, czy właściwe jest uzasadnienie H0 w tym bootstrapie na podstawie tego, że właśnie zebraliśmy próbki, z których pobraliśmy kolejne próbki?
Inne podejście znalazłem w kilku artykułach naukowych. W szczególności widziałem, że badacze modyfikują dane w celu spełnienia H0 przed rozpoczęciem ładowania. Rozglądając się, znalazłem bardzo interesujący post w CV, w którym @ jan.s wyjaśnił niezwykłe wyniki bootstrap w pytaniu, w którym celem było porównanie dwóch średnich. Jednak w tym poście nie opisano, jak wykonać bootstrap, gdy dane są modyfikowane przed bootstrapem. Podejście, w którym dane są modyfikowane przed rozpoczęciem ładowania wygląda następująco:
- H0 stwierdza, że średnie dwóch grup są takie same
- H0 jest prawdą, jeśli odejmiemy indywidualne obserwacje od średniej próbki zbiorczej
W takim przypadku modyfikacja danych powinna wpływać na średnie grup, a zatem na ich różnicę, ale nie na zmienność w obrębie grup (i między nimi).
- Zmodyfikowane dane będą podstawą do dalszego ładowania, z zastrzeżeniami, że próbkowanie jest przeprowadzane w ramach każdej grupy osobno .
- Różnicę między wartością początkową g1 i g2 oblicza się i porównuje z zaobserwowaną (niemodyfikowaną) różnicą między grupami.
- Proporcja równych lub większej liczby wartości ekstremalnych niż obserwowana podzielona przez liczbę iteracji da wartość p.
Oto kod (Bootstrap2: ponowne próbkowanie w grupach po modyfikacji, że H0 ma wartość PRAWDA ):
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.b2 <- mean (g1.lengths) - mean (g2.lengths)
# make H0 to be true (no difference between means of two groups)
H0 <- pool - mean (pool)
# g1 from H0
g1.H0 <- H0[1:s.size.g1]
# g2 from H0
g2.H0 <- H0[(s.size.g1+1):length(pool)]
iterations <- 10000
sampl.dist.b2 <- NULL
set.seed (5)
for (i in 1 : iterations) {
# Sample with replacement in g1
g1.boot = sample (g1.H0, replace = T)
# Sample with replacement in g2
g2.boot = sample (g2.H0, replace = T)
# bootstrapped difference
sampl.dist.b2[i] <- mean (g1.boot) - mean (g2.boot)
}
p.boot2 <- (sum (abs (sampl.dist.b2) >= obs.diff.b2) + 1)/ (iterations+1)
Tak wykonany bootstrap da wartość p 0,514, która jest ogromnie inna w porównaniu do poprzednich testów. Uważam, że ma to związek z wyjaśnieniem @ jan.s , ale nie mogę zrozumieć, gdzie jest klucz ...
H0 <- pool - mean (pool)
. Należy go zastąpićH0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths))
. Otrzymasz wartość p 0,0023. (To jest to samo, co Zenit wyjaśnił w swojej odpowiedzi.) To wszystko, tylko prosty błąd w kodzie. CC do @MichaelChernickOdpowiedzi:
Oto moje zdanie na ten temat, oparte na rozdziale 16 Efrona i Tibshirani's An Introduction to bootstrap (strona 220-224). Krótko mówiąc, twój drugi algorytm ładowania początkowego został nieprawidłowo zaimplementowany, ale ogólna idea jest poprawna.
Podczas przeprowadzania testów ładowania początkowego należy upewnić się, że metoda ponownego próbkowania generuje dane, które odpowiadają hipotezie zerowej. Użyję danych dotyczących snu w R, aby zilustrować ten post. Zauważ, że korzystam ze statystyk z testów uczniowskich, a nie tylko z różnic średnich, co jest zalecane w podręczniku.
Klasyczny test t, który wykorzystuje wynik analityczny do uzyskania informacji o rozkładzie próbkowania statystyki t, daje następujący wynik:
Tym razem otrzymaliśmy podobne wartości p dla trzech podejść. Mam nadzieję że to pomoże!
źródło
(1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)
zamiast czegoś takiego:mean(abs(boot.t) > abs(t.test(x,y)$statistic))
Dziękuję za poświęcony czas.