Насправді не дуже складно впоратися з гетероседастичністю у простих лінійних моделях (наприклад, одно- або двосторонні моделі, подібні до ANOVA).
Міцність ANOVA
По-перше, як зауважують інші, ANOVA надзвичайно стійкий до відхилень від припущення рівних дисперсій, особливо якщо у вас є приблизно збалансовані дані (однакова кількість спостережень у кожній групі). Попередні тести на рівних варіаціях, з іншого боку, не є (хоча тест Левене набагато кращий, ніж F -тест, який зазвичай навчають у підручниках). Як сказав Джордж Бокс:
Зробити попередній тест на відхилення - це як висадити в море на гребному човні, щоб з’ясувати, чи достатньо спокійних умов для того, щоб океанський лайнер вийшов з порту!
Навіть незважаючи на те, що ANOVA дуже надійний, тому що дуже легко врахувати гетероскедичність, мало причин цього не робити.
Непараметричні тести
Якщо вас справді цікавлять розбіжності в засобах , непараметричні тести (наприклад, тест Крускала – Уолліса) насправді не приносять користі. Вони роблять тест відмінність між групами, але вони НЕ в загальних тестах відмінностей в засобах.
Приклад даних
Створимо простий приклад даних, де хотілося б використовувати ANOVA, але де припущення про рівні відхилення не відповідає дійсності.
set.seed(1232)
pop = data.frame(group=c("A","B","C"),
mean=c(1,2,5),
sd=c(1,3,4))
d = do.call(rbind, rep(list(pop),13))
d$x = rnorm(nrow(d), d$mean, d$sd)
Ми маємо три групи з (чіткими) відмінностями як серед засобів, так і варіацій:
stripchart(x ~ group, data=d)
АНОВА
Не дивно, що нормальна ANOVA справляється з цим досить добре:
> mod.aov = aov(x ~ group, data=d)
> summary(mod.aov)
Df Sum Sq Mean Sq F value Pr(>F)
group 2 199.4 99.69 13.01 5.6e-05 ***
Residuals 36 275.9 7.66
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Отже, які групи відрізняються? Давайте скористаємось методом HSD Tukey:
> TukeyHSD(mod.aov)
Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = x ~ group, data = d)
$group
diff lwr upr p adj
B-A 1.736692 -0.9173128 4.390698 0.2589215
C-A 5.422838 2.7688327 8.076843 0.0000447
C-B 3.686146 1.0321403 6.340151 0.0046867
З значенням P 0,26, ми не можемо стверджувати про різницю (у засобах) між групами А та В. І навіть якби ми не врахували, що ми зробили три порівняння, ми не отримали низький P - значення ( P = 0,12):
> summary.lm(mod.aov)
[…]
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.5098 0.7678 0.664 0.511
groupB 1.7367 1.0858 1.599 0.118
groupC 5.4228 1.0858 4.994 0.0000153 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.768 on 36 degrees of freedom
Чому так? На основі сюжету, є це досить чітке розходження. Причина полягає в тому, що ANOVA приймає однакові відхилення в кожній групі і оцінює загальне стандартне відхилення 2,77 (показане як "Залишкова стандартна помилка" в summary.lm
таблиці, або ви можете отримати це, взявши квадратний корінь залишкового середнього квадрату (7,66) в таблиці ANOVA).
Але група А має стандартне відхилення (населення) 1, і це завищення 2,77 ускладнює отримання статистично значущих результатів, тобто у нас є тест з (занадто) низькою потужністю.
'ANOVA' з неоднаковими відхиленнями
Отже, як підігнати правильну модель, ту, яка враховує відмінності у відхиленнях? Це просто в R:
> oneway.test(x ~ group, data=d, var.equal=FALSE)
One-way analysis of means (not assuming equal variances)
data: x and group
F = 12.7127, num df = 2.000, denom df = 19.055, p-value = 0.0003107
Отже, якщо ви хочете запустити просту односторонню 'ANOVA' в R, не допускаючи рівних дисперсій, скористайтеся цією функцією. Це в основному розширення (Welch) t.test()
для двох зразків з неоднаковими варіаціями.
На жаль, це не працює TukeyHSD()
(або більшість інших функцій, які ви використовуєте на aov
об'єктах), тому навіть якщо ми впевнені, що існують групові відмінності, ми не знаємо, де вони.
Моделювання гетероседастичності
Найкраще рішення - чітко моделювати відхилення. І це дуже просто в R:
> library(nlme)
> mod.gls = gls(x ~ group, data=d,
weights=varIdent(form= ~ 1 | group))
> anova(mod.gls)
Denom. DF: 36
numDF F-value p-value
(Intercept) 1 16.57316 0.0002
group 2 13.15743 0.0001
Досі суттєві відмінності, звичайно. Але тепер відмінності між групами A і B також стали статично значущими ( P = 0,025):
> summary(mod.gls)
Generalized least squares fit by REML
Model: x ~ group
[…]
Variance function:
Structure: Different standard
deviations per stratum
Formula: ~1 | group
Parameter estimates:
A B C
1.000000 2.444532 3.913382
Coefficients:
Value Std.Error t-value p-value
(Intercept) 0.509768 0.2816667 1.809829 0.0787
groupB 1.736692 0.7439273 2.334492 0.0253
groupC 5.422838 1.1376880 4.766542 0.0000
[…]
Residual standard error: 1.015564
Degrees of freedom: 39 total; 36 residual
Тож використання відповідної моделі допомагає! Також зазначимо, що ми отримуємо оцінки (відносних) стандартних відхилень. Розрахункове стандартне відхилення для групи А можна знайти внизу, результати, 1,02. Розрахункове стандартне відхилення групи В в 2,44 рази більше, або 2,48, а розрахункове стандартне відхилення групи С приблизно 3,97 (тип intervals(mod.gls)
для отримання довірчих інтервалів для відносних стандартних відхилень груп В і С).
Виправлення для багаторазового тестування
Однак нам дійсно слід виправити багаторазове тестування. Це легко за допомогою бібліотеки "мультикомплект". На жаль, у нього немає вбудованої підтримки об’єктів 'gls', тому нам спочатку доведеться додати кілька допоміжних функцій:
model.matrix.gls <- function(object, ...)
model.matrix(terms(object), data = getData(object), ...)
model.frame.gls <- function(object, ...)
model.frame(formula(object), data = getData(object), ...)
terms.gls <- function(object, ...)
terms(model.frame(object),...)
Тепер приступимо до роботи:
> library(multcomp)
> mod.gls.mc = glht(mod.gls, linfct = mcp(group = "Tukey"))
> summary(mod.gls.mc)
[…]
Linear Hypotheses:
Estimate Std. Error z value Pr(>|z|)
B - A == 0 1.7367 0.7439 2.334 0.0480 *
C - A == 0 5.4228 1.1377 4.767 <0.001 ***
C - B == 0 3.6861 1.2996 2.836 0.0118 *
Досі статистично значуща різниця між групою А та групою В! ☺ І ми можемо отримати навіть (одночасні) довірчі інтервали для відмінностей між груповими засобами:
> confint(mod.gls.mc)
[…]
Linear Hypotheses:
Estimate lwr upr
B - A == 0 1.73669 0.01014 3.46324
C - A == 0 5.42284 2.78242 8.06325
C - B == 0 3.68615 0.66984 6.70245
Використовуючи приблизно (тут саме) правильну модель, ми можемо довіряти цим результатам!
Зауважимо, що для цього простого прикладу дані для групи C насправді не додають жодної інформації про відмінності між групами A і B, оскільки ми моделюємо як окремі засоби, так і стандартні відхилення для кожної групи. Ми могли просто використати парні t -тести, виправлені для кількох порівнянь:
> pairwise.t.test(d$x, d$group, pool.sd=FALSE)
Pairwise comparisons using t tests with non-pooled SD
data: d$x and d$group
A B
B 0.03301 -
C 0.00098 0.02032
P value adjustment method: holm
Однак для більш складних моделей, наприклад, двосторонніх моделей або лінійних моделей з багатьма предикторами, використання GLS (узагальнених найменших квадратів) та явного моделювання дисперсійних функцій є найкращим рішенням.
І функція дисперсії не повинна бути просто різною константою в кожній групі; ми можемо накласти їй структуру. Наприклад, ми можемо моделювати дисперсію як середню потужність кожної групи (і, таким чином, потрібно лише оцінити один параметр, показник) або, можливо, як логарифм одного з предикторів моделі. З GLS (і gls()
в R) все це дуже легко .
Узагальнені найменші квадрати - це ІМХО дуже недооцінений метод статистичного моделювання. Замість того, щоб турбуватися про відхилення від припущень моделі , моделюйте ці відхилення!
R
, це може вам корисно, прочитавши мою відповідь тут: Альтернативи односторонній ANOVA для гетеросептичних даних , де обговорюються деякі з цих питань.