Sebenarnya tidak terlalu sulit untuk menangani heteroskedastisitas dalam model linier sederhana (misalnya, model mirip ANOVA satu atau dua arah).
Kuatnya ANOVA
Pertama, seperti yang diketahui orang lain, ANOVA sangat kuat untuk penyimpangan dari asumsi varians yang sama, terutama jika Anda memiliki data yang seimbang (jumlah pengamatan yang sama di setiap kelompok). Tes pendahuluan pada varian yang sama, selain itu, tidak (meskipun tes Levene jauh lebih baik daripada uji- F yang biasa diajarkan dalam buku teks). Seperti yang dikatakan George Box:
Untuk membuat uji pendahuluan atas varian-variasinya agak seperti melaut di atas perahu dayung untuk mengetahui apakah kondisinya cukup tenang bagi seorang pelaut untuk meninggalkan pelabuhan!
Meskipun ANOVA sangat kuat, karena sangat mudah untuk memperhitungkan heteroskedastisitas, hanya ada sedikit alasan untuk tidak melakukannya.
Tes non-parametrik
Jika Anda benar-benar tertarik pada perbedaan dalam cara , tes non-parametrik (misalnya, tes Kruskal-Wallis) benar-benar tidak ada gunanya. Mereka menguji perbedaan antar kelompok, tetapi mereka tidak menguji perbedaan rata-rata secara umum.
Contoh data
Mari kita buat contoh sederhana dari data di mana orang ingin menggunakan ANOVA, tetapi di mana asumsi varian yang sama tidak benar.
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)
Kami memiliki tiga kelompok, dengan (jelas) perbedaan dalam cara dan varians:
stripchart(x ~ group, data=d)
ANOVA
Tidak mengherankan, ANOVA yang normal menangani ini dengan cukup baik:
> 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
Jadi, kelompok mana yang berbeda? Mari kita gunakan metode 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
Dengan nilai- P dari 0,26, kami tidak dapat mengklaim perbedaan (dalam arti) antara kelompok A dan B. Dan bahkan jika kami tidak memperhitungkan bahwa kami melakukan tiga perbandingan, kami tidak akan mendapatkan P yang rendah - nilai ( 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
Mengapa demikian? Berdasarkan plot, ada adalah perbedaan cukup jelas. Alasannya adalah bahwa ANOVA mengasumsikan varians yang sama di setiap kelompok, dan memperkirakan standar deviasi 2,77 (ditampilkan sebagai 'Kesalahan standar residual' disummary.lm
tabel, atau Anda bisa mendapatkannya dengan mengambil akar kuadrat dari kuadrat residual rata-rata (7,66) dalam tabel ANOVA).
Tetapi kelompok A memiliki (populasi) standar deviasi 1, dan perkiraan terlalu tinggi dari 2,77 ini membuat (tidak perlu) sulit untuk mendapatkan hasil yang signifikan secara statistik, yaitu, kami memiliki tes dengan (terlalu) daya rendah.
'ANOVA' dengan varian yang tidak sama
Jadi, bagaimana cara mencocokkan model yang tepat, model yang memperhitungkan perbedaan varian? Mudah di 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
Jadi, jika Anda ingin menjalankan 'ANOVA' satu arah yang sederhana dalam R tanpa mengasumsikan varian yang sama, gunakan fungsi ini. Ini pada dasarnya merupakan perpanjangan dari (Welch) t.test()
untuk dua sampel dengan varian yang tidak sama.
Sayangnya, itu tidak bekerja dengan TukeyHSD()
(atau sebagian besar fungsi lain yang Anda gunakan pada aov
objek), sehingga bahkan jika kami cukup yakin ada yang perbedaan kelompok, kita tidak tahu di mana mereka berada.
Pemodelan heteroskedastisitas
Solusi terbaik adalah memodelkan varians secara eksplisit. Dan itu sangat mudah di 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
Perbedaan masih signifikan, tentu saja. Tetapi sekarang perbedaan antara kelompok A dan B juga menjadi signifikan secara statis ( 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
Jadi menggunakan model yang tepat membantu! Juga catat bahwa kita mendapatkan perkiraan standar deviasi (relatif). Estimasi standar deviasi untuk grup A dapat ditemukan di bagian bawah, hasil, 1,02. Estimasi standar deviasi grup B adalah 2,44 kali ini, atau 2,48, dan estimasi standar deviasi grup C adalah 3,97 (tipe intervals(mod.gls)
untuk mendapatkan interval kepercayaan untuk standar deviasi relatif grup B dan C).
Memperbaiki untuk beberapa pengujian
Namun, kami harus benar-benar memperbaiki beberapa pengujian. Ini mudah menggunakan perpustakaan 'multcomp'. Sayangnya, itu tidak memiliki dukungan bawaan untuk objek 'gls', jadi kita harus menambahkan beberapa fungsi pembantu terlebih dahulu:
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),...)
Sekarang mari kita mulai bekerja:
> 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 *
Masih ada perbedaan yang signifikan secara statistik antara kelompok A dan kelompok B! ☺ Dan kita bahkan bisa mendapatkan interval kepercayaan (simultan) untuk perbedaan antara cara kelompok:
> 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
Dengan menggunakan kira-kira (di sini tepatnya) model yang benar, kami dapat mempercayai hasil ini!
Perhatikan bahwa untuk contoh sederhana ini, data untuk grup C tidak benar-benar menambahkan informasi tentang perbedaan antara grup A dan B, karena kami memodelkan cara terpisah dan standar deviasi untuk masing-masing grup. Kami bisa saja menggunakan uji- t berpasangan yang dikoreksi untuk beberapa perbandingan:
> 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
Namun, untuk model yang lebih rumit, misalnya, model dua arah, atau model linier dengan banyak prediktor, menggunakan GLS (generalised least square) dan secara eksplisit memodelkan fungsi varians adalah solusi terbaik.
Dan fungsi varians tidak perlu hanya menjadi konstanta yang berbeda di setiap kelompok; kita bisa memaksakan struktur padanya. Sebagai contoh, kita dapat memodelkan varians sebagai kekuatan dari rata - rata setiap kelompok (dan dengan demikian hanya perlu memperkirakan satu parameter, eksponen), atau mungkin sebagai logaritma dari salah satu prediktor dalam model. Semua ini sangat mudah dengan GLS (dan gls()
dalam R).
Kuadrat terkecil yang digeneralisasikan adalah IMHO teknik pemodelan statistik yang sangat jarang digunakan. Alih-alih mengkhawatirkan penyimpangan dari asumsi model , modelkan penyimpangan itu!
R
, mungkin bermanfaat bagi Anda untuk membaca jawaban saya di sini: Alternatif untuk ANOVA satu arah untuk data heteroskedastik , yang membahas beberapa masalah ini.