Припустимо, у мене є дані з двома незалежними групами:
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 (значення p становить 0,0044 ).
summary (aov (lengths~group, data = lengths))
З огляду на те, що моя мета полягає в порівнянні середньої різниці, такі незбалансовані та малі вибіркові дані можуть дати невідповідні результати з традиційним підходом. Тому я хочу виконати тест на перестановку та завантажувальний інструмент.
ВИПУСКОВИЙ ТЕСТ
Нульова гіпотеза (H0) стверджує, що засоби групи однакові. Це припущення в перестановковому тесті є виправданим об'єднанням груп в один зразок. Це гарантує, що зразки для двох груп були взяті з однакового розподілу. Шляхом повторного відбору проб (а точніше - перестановки) зібраних даних спостереження перерозподіляються (перетасовуються) до зразків по-новому, і обчислюється статистика тесту. Виконавши це n разів, дасть вибіркове розподіл тестової статистики за припущенням, де H0 - ІСТИНА. Зрештою, під значенням H0 р значення - ймовірність того, що статистика тесту дорівнює або перевищує спостережуване значення.
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 дають майже однакові результати.
BOOTSTRAP
Перш за все, я знаю, що завантажувальна програма не може допомогти, коли розміри вибірки занадто малі. Цей пост показав, що це може бути ще гірше і вводити в оману . Крім того, другий підкреслював, що тест на перестановку, як правило, кращий, ніж завантажувальний, коли головна мета тестування гіпотез. Тим не менш, цей чудовий пост вирішує важливі відмінності між комп'ютерними методами. Однак тут я хочу поставити (я вважаю) інше питання.
Дозвольте спочатку представити найбільш поширений підхід до завантаження (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 є ПРАВИЛЬНИМ ):
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))
. Тоді ви отримаєте p-значення 0,0023. (Це те саме, що пояснив Зеніт у своїй відповіді.) Це все, що є, просто проста помилка в коді. CC до @MichaelChernick