Предположим, у меня есть данные с двумя независимыми группами:
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)
Очевидно, что размер выборки на группу смещен, где g1 имеет 6 наблюдений, а g2 имеет 22 . Традиционный ANOVA предполагает, что группы имеют разные средние значения, когда критическое значение установлено на 0,05 (значение р равно 0,0044 ).
summary (aov (lengths~group, data = lengths))
Учитывая, что моя цель состоит в том, чтобы сравнить среднюю разницу, такие несбалансированные и небольшие выборочные данные могут дать неадекватные результаты с традиционным подходом. Поэтому я хочу выполнить тест перестановки и начальную загрузку.
Тест на разогрев
Нулевая гипотеза (H0) утверждает, что средние группы одинаковы. Это предположение в тесте перестановки оправдывается объединением групп в одну выборку. Это гарантирует, что образцы для двух групп были взяты из идентичного распределения. Путем повторной выборки (или, точнее, перестановки) из объединенных данных, наблюдения перераспределяются (перетасовываются) в выборки по-новому, и вычисляется статистика испытаний. Выполнение этого n раз даст выборочное распределение статистики теста в предположении, что H0 - ИСТИНА. В конце, под H0, значение p является вероятностью того, что тестовая статистика равна или превышает наблюдаемое значение.
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)
Сообщаемое значение p теста перестановки составляет 0,0053 . Хорошо, если я сделал это правильно, перестановки и параметрический ANOVA дают почти идентичные результаты.
начальная загрузка
Прежде всего, я знаю, что начальная загрузка не может помочь, когда размеры выборки слишком малы. Этот пост показал, что он может быть еще хуже и вводить в заблуждение . Кроме того, второй подчеркнул, что тест перестановки, как правило, лучше, чем начальный тест, когда проверка гипотез является основной целью. Тем не менее, этот великий пост посвящен важным различиям между компьютерными методами. Однако здесь я хочу поднять (я полагаю) другой вопрос.
Позвольте мне сначала представить наиболее распространенный метод начальной загрузки (Bootstrap1: повторная выборка в объединенном образце ):
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)
Значение P бутстрапа, выполненного таким образом, составляет 0,005 . Даже если это звучит разумно и почти идентично параметрическому ANOVA и тесту перестановки, уместно ли обосновывать H0 в этой начальной загрузке на основе того, что мы только что объединили выборки, из которых мы взяли последующие выборки?
Другой подход я нашел в нескольких научных работах. В частности, я увидел, что исследователи модифицируют данные, чтобы соответствовать H0 до начальной загрузки. Осматривая, я нашел очень интересную запись в CV, где @ jan.s объяснил необычные результаты начальной загрузки в вопросе, где целью было сравнить два средства. Тем не менее, в этом посте не рассматривается, как выполнить загрузку, когда данные изменяются до начальной загрузки. Подход, при котором данные модифицируются до начальной загрузки, выглядит следующим образом:
- H0 утверждает, что средства двух групп одинаковы
- H0 верен, если мы вычтем отдельные наблюдения из среднего значения выборки
В этом случае модификация данных должна влиять на групповые средства и, следовательно, на их различие, но не на вариацию внутри (и между) группами.
- Модифицированные данные будут основой для дальнейшей начальной загрузки, с оговорками, что выборка проводится в каждой группе отдельно .
- Разница между начальным значением g1 и g2 рассчитывается и сравнивается с наблюдаемой (неизмененной) разницей между группами.
- Пропорция равных или более экстремальных значений, чем наблюдаемое, деленное на число итераций, даст значение p.
Вот код (Bootstrap2: повторная выборка внутри групп после модификации, что H0 TRUE ):
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)
Такой выполненный начальный загрузчик даст значение р 0,514, которое сильно отличается от предыдущих тестов. Я считаю, что это связано с объяснением @ jan.s , но я не могу понять, где ключ ...
H0 <- pool - mean (pool)
. Это должно быть заменено наH0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths))
. Тогда вы получите р-значение 0,0023. (Это то же самое, что Зенит объяснил в своем ответе.) Это все, что нужно сделать, просто простая ошибка в коде. CC @MichaelChernickОтветы:
Вот мой взгляд на это, основанный на главе 16 « Введение в бутстрап» Эфрона и Тибширани (стр. 220-224). Суть в том, что ваш второй алгоритм начальной загрузки был реализован неправильно, но общая идея верна.
При проведении тестов начальной загрузки необходимо убедиться, что метод повторной выборки генерирует данные, которые соответствуют нулевой гипотезе. Я буду использовать данные сна в R, чтобы проиллюстрировать этот пост. Обратите внимание, что я использую статистические данные о тестировании, а не просто разницу в средствах, что рекомендуется в учебнике.
Классический t-критерий, который использует аналитический результат для получения информации о распределении выборки t-статистики, дает следующий результат:
Один из подходов по духу аналогичен более известному тесту перестановок: образцы отбираются по всему набору наблюдений, при этом игнорируются метки группировки. Затем первые присваиваются первой группе, а оставшиеся - второй группе.№ 1 п 2
Однако этот алгоритм фактически проверяет, являются ли распределения x и y одинаковыми. Если нас просто интересует, равны ли их популяции, без каких-либо предположений об их дисперсии, мы должны сгенерировать данные в немного другим способом. Вы были на правильном пути с вашим подходом, но ваш перевод на немного отличается от того, который предложен в учебнике. Чтобы сгенерировать нам нужно вычесть среднее из первой группы из наблюдений в первой группе, а затем добавить общее или объединенное среднее . Для второй группы мы делаем то же самое.ЧАС0 ЧАС0 ЧАС0 Z¯
Это становится более интуитивным, когда вы вычисляете средние значения новых переменных . Сначала вычитая их соответствующие групповые значения, переменные становятся центрированными вокруг нуля. Добавляя общее среднее значение мы получаем выборку наблюдений, сосредоточенную вокруг общего среднего значения. Другими словами, мы преобразовали наблюдения таким образом, чтобы они имели одинаковое среднее значение, которое также является общим средним значением обеих групп, которое в точности равно .Икс~/ у~ Z¯ ЧАС0
На этот раз мы получили схожие значения р для трех подходов. Надеюсь это поможет!
источник
(1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)
вместо чего-то вроде этого:mean(abs(boot.t) > abs(t.test(x,y)$statistic))
Спасибо за ваше время.