Існує ряд варіантів, що стосуються гетеросептичних даних. На жаль, жоден з них не гарантовано завжди працює. Ось кілька варіантів, з якими я знайомий:
- трансформації
- Welch ANOVA
- зважені найменші квадрати
- міцна регресія
- гетероскедастичність відповідає стандартним помилкам
- завантажувач
- Тест Крускала-Уолліса
- порядкова логістична регресія
Оновлення: Ось демонстрація R
деяких способів пристосування лінійної моделі (наприклад, ANOVA або регресія), коли у вас дисперсія гетероцедастичності / гетерогенності.
Для початку поглянемо на ваші дані. Для зручності я завантажую їх у два кадри даних, які називаються my.data
(які структуровані, як вище, з одним стовпцем на групу) та stacked.data
(який має два стовпці: values
з номерами та ind
з індикатором групи).
Ми можемо офіційно перевірити на гетероцедастичність за допомогою тесту Левене:
library(car)
leveneTest(values~ind, stacked.data)
# Levene's Test for Homogeneity of Variance (center = median)
# Df F value Pr(>F)
# group 2 8.1269 0.001153 **
# 38
Звичайно, у вас гетероскедастичність. Ми перевіримо, що таке дисперсії груп. Основне правило полягає в тому, що лінійні моделі є досить стійкими до неоднорідності дисперсії до тих пір, поки максимальна дисперсія не більше більша за мінімальну дисперсію, тому ми знайдемо і це співвідношення: 4×
apply(my.data, 2, function(x){ var(x, na.rm=T) })
# A B C
# 0.01734578 0.33182844 0.06673060
var(my.data$B, na.rm=T) / var(my.data$A, na.rm=T)
# [1] 19.13021
Ваші дисперсії істотно відрізняються, з найбільшим, B
, будучи найменший . Це проблематичний рівень гетеросцесматичності. 19×A
Ви думали використовувати перетворення, такі як лог або квадратний корінь, щоб стабілізувати дисперсію. Це буде спрацьовувати в деяких випадках, але перетворення типу Box-Cox стабілізують дисперсію, видаляючи дані несиметрично, або стискаючи їх донизу з найвищими даними, що видаляються найбільше, або видавлюючи їх вгору з найнижчими даними, видаленими найбільше. Таким чином, вам потрібна дисперсія ваших даних, щоб змінити її із середнім рівнем для оптимальної роботи. Ваші дані відрізняються величезною різницею, але порівняно невелика різниця між засобами та медіанами, тобто розподіли здебільшого збігаються. Як навчальну вправу, ми можемо створити деякі parallel.universe.data
, додавши до всіх значень і2.7B
.7C
, щоб показати, як це буде працювати:
parallel.universe.data = with(my.data, data.frame(A=A, B=B+2.7, C=C+.7))
apply(parallel.universe.data, 2, function(x){ var(x, na.rm=T) })
# A B C
# 0.01734578 0.33182844 0.06673060
apply(log(parallel.universe.data), 2, function(x){ var(x, na.rm=T) })
# A B C
# 0.12750634 0.02631383 0.05240742
apply(sqrt(parallel.universe.data), 2, function(x){ var(x, na.rm=T) })
# A B C
# 0.01120956 0.02325107 0.01461479
var(sqrt(parallel.universe.data$B), na.rm=T) /
var(sqrt(parallel.universe.data$A), na.rm=T)
# [1] 2.074217
Використання квадратного перетворення кореня досить добре стабілізує ці дані. Поліпшення даних про паралельні Всесвіту ви можете побачити тут:
Замість того, щоб просто пробувати різні перетворення, більш системним підходом є оптимізація параметра Box-Cox λλ = .5λ = 0
boxcox(values~ind, data=stacked.data, na.action=na.omit)
boxcox(values~ind, data=stacked.pu.data, na.action=na.omit)
Жdf = 19.445
df = 38
oneway.test(values~ind, data=stacked.data, na.action=na.omit, var.equal=FALSE)
# One-way analysis of means (not assuming equal variances)
#
# data: values and ind
# F = 4.1769, num df = 2.000, denom df = 19.445, p-value = 0.03097
Більш загальний підхід - використовувати зважені найменші квадрати . Оскільки деякі групи ( B
) поширюються більше, дані цих груп надають менше інформації про розташування середнього значення, ніж дані в інших групах. Ми можемо дозволити моделі включити це, надаючи вагу кожній точці даних. Загальна система полягає у використанні зворотної дисперсії групи як ваги:
wl = 1 / apply(my.data, 2, function(x){ var(x, na.rm=T) })
stacked.data$w = with(stacked.data, ifelse(ind=="A", wl[1],
ifelse(ind=="B", wl[2], wl[3])))
w.mod = lm(values~ind, stacked.data, na.action=na.omit, weights=w)
anova(w.mod)
# Response: values
# Df Sum Sq Mean Sq F value Pr(>F)
# ind 2 8.64 4.3201 4.3201 0.02039 *
# Residuals 38 38.00 1.0000
Жp4.5089
0.01749
Однак найважчі квадрати не є панацеєю. Один незручний факт - це те, що лише тоді, коли ваги є правильними, тобто, серед іншого, це означає, що вони апріорі відомі. Він також не стосується ненормативності (наприклад, перекосу) або інших людей. Використання ваг, оцінених за вашими даними, часто спрацює нормально, особливо якщо у вас є достатньо даних, щоб оцінити дисперсію з розумною точністю (це аналогічно ідеї використанняzт50100N
1 / apply(my.data, 2, function(x){ var(x, na.rm=T) })
# A B C
# 57.650907 3.013606 14.985628
1 / apply(my.data, 2, function(x){ IQR(x, na.rm=T) })
# A B C
# 9.661836 1.291990 4.878049
rw = 1 / apply(my.data, 2, function(x){ IQR(x, na.rm=T) })
stacked.data$rw = with(stacked.data, ifelse(ind=="A", rw[1],
ifelse(ind=="B", rw[2], rw[3])))
library(robustbase)
w.r.mod = lmrob(values~ind, stacked.data, na.action=na.omit, weights=rw)
anova(w.r.mod, lmrob(values~1,stacked.data,na.action=na.omit,weights=rw), test="Wald")
# Robust Wald Test Table
#
# Model 1: values ~ ind
# Model 2: values ~ 1
# Largest model fitted by lmrob(), i.e. SM
#
# pseudoDf Test.Stat Df Pr(>chisq)
# 1 38
# 2 40 6.6016 2 0.03685 *
Ваги тут не такі екстремальні. Прогнозовані кошти групи незначно відрізняються ( A
: WLS 0.36673
, надійним 0.35722
; B
: ВМНК 0.77646
, надійним 0.70433
; C
: WLS 0.50554
, надійний 0.51845
), за допомогою B
і C
того менше тягнуть екстремальних значення.
У економетриці великою популярністю користується стандартна помилка Губер-Білого («сендвіч») . Як і корекція Welch, це не вимагає, щоб ви знали відхилення a-priori, і не вимагало від вас оцінювати ваги за вашими даними та / або залежно від моделі, яка може бути невірною. З іншого боку, я не знаю, як це поєднати з ANOVA, це означає, що ви отримуєте їх лише для тестів окремих фіктивних кодів, що вважає мене менш корисним у цьому випадку, але я все одно продемонструю їх:
library(sandwich)
mod = lm(values~ind, stacked.data, na.action=na.omit)
sqrt(diag(vcovHC(mod)))
# (Intercept) indB indC
# 0.03519921 0.16997457 0.08246131
2*(1-pt(coef(mod) / sqrt(diag(vcovHC(mod))), df=38))
# (Intercept) indB indC
# 1.078249e-12 2.087484e-02 1.005212e-01
vcovHC
ттт
Для R
car
white.adjust
p
Anova(mod, white.adjust=TRUE)
# Analysis of Deviance Table (Type II tests)
#
# Response: values
# Df F Pr(>F)
# ind 2 3.9946 0.02663 *
# Residuals 38
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
ЖЖp
mod = lm(values~ind, stacked.data, na.action=na.omit)
F.stat = anova(mod)[1,4]
# create null version of the data
nullA = my.data$A - mean(my.data$A)
nullB = my.data$B - mean(my.data$B, na.rm=T)
nullC = my.data$C - mean(my.data$C, na.rm=T)
set.seed(1)
F.vect = vector(length=10000)
for(i in 1:10000){
A = sample(na.omit(nullA), 15, replace=T)
B = sample(na.omit(nullB), 13, replace=T)
C = sample(na.omit(nullC), 13, replace=T)
boot.dat = stack(list(A=A, B=B, C=C))
boot.mod = lm(values~ind, boot.dat)
F.vect[i] = anova(boot.mod)[1,4]
}
1-mean(F.stat>F.vect)
# [1] 0.0485
н
kruskal.test(values~ind, stacked.data, na.action=na.omit)
# Kruskal-Wallis rank sum test
#
# data: values by ind
# Kruskal-Wallis chi-squared = 5.7705, df = 2, p-value = 0.05584
Хоча тест Крускала-Уолліса, безумовно, є найкращим захистом від помилок типу I, він може бути використаний лише з однією категоріальною змінною (тобто відсутність безперервних прогнозів чи факторних конструкцій), і він має найменшу потужність з усіх обговорюваних стратегій. Іншим непараметричним підходом є використання порядкової логістичної регресії . Для багатьох людей це здається дивним, але вам потрібно лише припустити, що ваші дані відповідей містять законну порядкову інформацію, яку вони, безумовно, роблять, або будь-яка інша стратегія, зазначена вище, також недійсна:
library(rms)
olr.mod = orm(values~ind, stacked.data)
olr.mod
# Model Likelihood Discrimination Rank Discrim.
# Ratio Test Indexes Indexes
# Obs 41 LR chi2 6.63 R2 0.149 rho 0.365
# Unique Y 41 d.f. 2 g 0.829
# Median Y 0.432 Pr(> chi2) 0.0363 gr 2.292
# max |deriv| 2e-04 Score chi2 6.48 |Pr(Y>=median)-0.5| 0.179
# Pr(> chi2) 0.0391
chi2
Discrimination Indexes
p -значення 0.0363
.