Использование начальной загрузки под H0 для проведения теста на разницу двух средств: замена в группах или в объединенном образце

18

Предположим, у меня есть данные с двумя независимыми группами:

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 объяснил необычные результаты начальной загрузки в вопросе, где целью было сравнить два средства. Тем не менее, в этом посте не рассматривается, как выполнить загрузку, когда данные изменяются до начальной загрузки. Подход, при котором данные модифицируются до начальной загрузки, выглядит следующим образом:

  1. H0 утверждает, что средства двух групп одинаковы
  2. H0 верен, если мы вычтем отдельные наблюдения из среднего значения выборки

В этом случае модификация данных должна влиять на групповые средства и, следовательно, на их различие, но не на вариацию внутри (и между) группами.

  1. Модифицированные данные будут основой для дальнейшей начальной загрузки, с оговорками, что выборка проводится в каждой группе отдельно .
  2. Разница между начальным значением g1 и g2 рассчитывается и сравнивается с наблюдаемой (неизмененной) разницей между группами.
  3. Пропорция равных или более экстремальных значений, чем наблюдаемое, деленное на число итераций, даст значение 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 , но я не могу понять, где ключ ...

Newbie_R
источник
1
Интересная проблема и красиво представлена. У начальной загрузки возникают проблемы, когда размер выборки очень мал только потому, что исходная выборка, скорее всего, не очень хорошо представляет популяцию. Размер выборки не обязательно должен быть очень большим для начальной загрузки. Размеры ваших выборок 6 и 22 могут быть не такими уж плохими. В работе Efron (1983) начальный загрузчик сравнивался с формой CV для оценки частоты ошибок для линейных дискриминантных функций в задачах классификации с двумя классами, где каждый размер обучающей выборки меньше 10. Я рассматриваю это в своей книге «Методы начальной загрузки» ( 2007).
Майкл Р. Черник
2
В моей книге также есть глава о том, когда происходит сбой начальной загрузки, и в ней обсуждается проблема малого размера выборки.
Майкл Р. Черник
Сингл строки , которые нужно исправить в своей начальной загрузки # 2 подхода , чтобы сделать его работу это одна: H0 <- pool - mean (pool). Это должно быть заменено на H0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths)). Тогда вы получите р-значение 0,0023. (Это то же самое, что Зенит объяснил в своем ответе.) Это все, что нужно сделать, просто простая ошибка в коде. CC @MichaelChernick
амеба говорит восстановить Монику
Могут ли эти методы быть подавлены? Я имею в виду, могут ли они определить ЛЮБУЮ разницу как значительную, когда группы очень большие: пул> 43k.
Алекс Альварес Перес

Ответы:

17

Вот мой взгляд на это, основанный на главе 16 « Введение в бутстрап» Эфрона и Тибширани (стр. 220-224). Суть в том, что ваш второй алгоритм начальной загрузки был реализован неправильно, но общая идея верна.

При проведении тестов начальной загрузки необходимо убедиться, что метод повторной выборки генерирует данные, которые соответствуют нулевой гипотезе. Я буду использовать данные сна в R, чтобы проиллюстрировать этот пост. Обратите внимание, что я использую статистические данные о тестировании, а не просто разницу в средствах, что рекомендуется в учебнике.

Классический t-критерий, который использует аналитический результат для получения информации о распределении выборки t-статистики, дает следующий результат:

x <- sleep$extra[sleep$group==1] y <- sleep$extra[sleep$group==2]
t.test(x,y)
t = -1.8608, df = 17.776, p-value = 0.07939

Один из подходов по духу аналогичен более известному тесту перестановок: образцы отбираются по всему набору наблюдений, при этом игнорируются метки группировки. Затем первые присваиваются первой группе, а оставшиеся - второй группе.N1N2

# pooled sample, assumes equal variance
pooled <- c(x,y)
for (i in 1:10000){
  sample.index <- sample(c(1:length(pooled)),replace=TRUE)
  sample.x <- pooled[sample.index][1:length(x)]
  sample.y <- pooled[sample.index][-c(1:length(y))]
  boot.t[i] <- t.test(sample.x,sample.y)$statistic
}
p.pooled <-  (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1) 
p.pooled
[1] 0.07929207

Однако этот алгоритм фактически проверяет, являются ли распределения x и y одинаковыми. Если нас просто интересует, равны ли их популяции, без каких-либо предположений об их дисперсии, мы должны сгенерировать данные в немного другим способом. Вы были на правильном пути с вашим подходом, но ваш перевод на немного отличается от того, который предложен в учебнике. Чтобы сгенерировать нам нужно вычесть среднее из первой группы из наблюдений в первой группе, а затем добавить общее или объединенное среднее . Для второй группы мы делаем то же самое.ЧАС0ЧАС0ЧАС0Z¯

Икс~язнак равноИкся-Икс¯+Z¯
Y~язнак равноYя-Y¯+Z¯

Это становится более интуитивным, когда вы вычисляете средние значения новых переменных . Сначала вычитая их соответствующие групповые значения, переменные становятся центрированными вокруг нуля. Добавляя общее среднее значение мы получаем выборку наблюдений, сосредоточенную вокруг общего среднего значения. Другими словами, мы преобразовали наблюдения таким образом, чтобы они имели одинаковое среднее значение, которое также является общим средним значением обеих групп, которое в точности равно .Икс~/Y~Z¯ЧАС0

# sample from H0 separately, no assumption about equal variance
xt <- x - mean(x) + mean(sleep$extra) #
yt <- y - mean(y) + mean(sleep$extra)

boot.t <- c(1:10000)
for (i in 1:10000){
  sample.x <- sample(xt,replace=TRUE)
  sample.y <- sample(yt,replace=TRUE)
  boot.t[i] <- t.test(sample.x,sample.y)$statistic
}
p.h0 <-  (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)  # 
p.h0
[1] 0.08049195

На этот раз мы получили схожие значения р для трех подходов. Надеюсь это поможет!

Зенит
источник
1
Не могли бы вы быть добрыми и объяснить, почему «1» был добавлен к следующему: (1 + sum(abs(boot.t) > abs(t.test(x,y)$statistic))) / (10000+1)вместо чего-то вроде этого: mean(abs(boot.t) > abs(t.test(x,y)$statistic))Спасибо за ваше время.
TG_Montana
+1. Имеет ли этот подход начальной загрузки по измененным данным к выборке из H0 конкретное имя?
говорит амеба: восстанови
3
@TG_Montana: общая идея состоит в том, что вы вычисляете долю статистики загруженных тестов (т. Под ), которая является более экстремальной (в любом направлении), чем наблюдаемая статистика тестов: , где - количество имитаций начальной загрузки. Меня учили добавлять 1 к числителю и знаменателю, чтобы избежать численных проблем (0), и в некотором смысле включить исходное наблюдение в качестве одной из симуляций. Смотрите раздел 7.1 здесь: arxiv.org/pdf/1411.5279.pdfЧАС0п-vaLUезнак равноколичество раз {T*>Tобs}ВВ
Зенит,
@amoeba: Я не уверен, что у этой процедуры есть формальное или согласованное имя, но я думаю, что это можно описать как загрузочный тест на равенство средств , а не как распределение . Страница, показывающая всю процедуру, отсутствует в книгах Google , но ее мотивация указана на странице 223. Другое описание этого можно найти в этих заметках на странице 13 ( galton.uchicago.edu/~eichler/stat24600/Handouts/bootstrap. pdf )
Зенит
(+1) Отличный ответ. Не могли бы вы пояснить, почему «этот алгоритм (передискретизация самих данных без центрирования) фактически проверяет, являются ли распределения x и y идентичными»? Я понимаю, что эта стратегия повторной выборки гарантирует, что распределения одинаковы, но почему проверяется, что они одинаковы?
полупансион