มันไม่จริงยากมากที่จะจัดการ heteroscedasticity ในโมเดลเชิงเส้นอย่างง่าย (เช่นโมเดล ANOVA แบบหนึ่งหรือสองทาง)
ความทนทานของ ANOVA
ก่อนอื่นตามที่คนอื่น ๆ ทราบ ANOVA นั้นแข็งแกร่งอย่างน่าอัศจรรย์ในการเบี่ยงเบนจากสมมติฐานของความแปรปรวนที่เท่ากันโดยเฉพาะอย่างยิ่งถ้าคุณมีข้อมูลที่สมดุลประมาณ (จำนวนการสังเกตที่เท่ากันในแต่ละกลุ่ม) การทดสอบเบื้องต้นเกี่ยวกับความแปรปรวนที่เท่ากันในทางกลับกันไม่ได้ (แม้ว่าการทดสอบของ Levene นั้นจะดีกว่าแบบทดสอบF -test ทั่วไปในตำราเรียน) ดังที่ George Box กล่าวไว้:
เพื่อให้การทดสอบเบื้องต้นเกี่ยวกับความแปรปรวนค่อนข้างเหมือนกับการลงทะเลในเรือพายเพื่อดูว่าเงื่อนไขสงบพอสำหรับเรือเดินสมุทรออกจากท่าเรือหรือไม่!
แม้ว่า ANOVA นั้นแข็งแกร่งมากเนื่องจากเป็นเรื่องง่ายมากที่จะคำนึงถึงความแตกต่างระหว่างกัน แต่ก็มีเหตุผลเล็กน้อยที่จะไม่ทำเช่นนั้น
การทดสอบแบบไม่มีพารามิเตอร์
หากคุณสนใจในความแตกต่างของค่าเฉลี่ยการทดสอบที่ไม่ใช่พารามิเตอร์ (เช่นการทดสอบ Kruskal – Wallis) นั้นไม่มีประโยชน์ใด ๆ พวกเขาทดสอบความแตกต่างระหว่างกลุ่ม แต่ไม่ทำอยู่ในวิธีทดสอบทั่วไป
ตัวอย่างข้อมูล
มาสร้างตัวอย่างง่ายๆของข้อมูลที่ใครอยากใช้ 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 เราไม่สามารถเรียกร้องความแตกต่างใด ๆ (ในความหมาย) ระหว่างกลุ่ม A และ B และแม้ว่าเราไม่ได้คำนึงถึงว่าเราทำการเปรียบเทียบสามครั้งเราจะไม่ได้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)
แต่กลุ่ม A มีค่าเบี่ยงเบนมาตรฐาน (ประชากร) เท่ากับ 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
ดังนั้นการใช้แบบจำลองที่เหมาะสมจะช่วยได้! นอกจากนี้โปรดทราบว่าเราได้รับการประมาณค่าเบี่ยงเบนมาตรฐาน (ญาติ) ค่าเบี่ยงเบนมาตรฐานโดยประมาณของกลุ่ม A สามารถพบได้ที่ด้านล่างของผลลัพธ์ 1.02 ค่าเบี่ยงเบนมาตรฐานโดยประมาณของกลุ่ม B คือ 2.44 คูณนี่หรือ 2.48 และค่าเบี่ยงเบนมาตรฐานโดยประมาณของกลุ่ม C เท่ากับ 3.97 (ประเภทintervals(mod.gls)
เพื่อรับช่วงความมั่นใจสำหรับการเบี่ยงเบนมาตรฐานสัมพัทธ์ของกลุ่ม B และ C)
การแก้ไขสำหรับการทดสอบหลายรายการ
อย่างไรก็ตามเราควรแก้ไขให้ถูกต้องสำหรับการทดสอบหลาย ๆ ครั้ง นี่เป็นเรื่องง่ายโดยใช้ไลบรารี่ 'multcomp' น่าเสียดายที่มันไม่มีการสนับสนุนในตัวสำหรับวัตถุ '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 *
ยังคงมีความแตกต่างอย่างมีนัยสำคัญระหว่างกลุ่ม A และกลุ่ม B! ☺และเรายังสามารถรับช่วงความมั่นใจ (พร้อมกัน) สำหรับความแตกต่างระหว่างกลุ่มหมายความว่า:
> 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)
สี่เหลี่ยมจัตุรัสทั่วไปที่น้อยที่สุดคือ IMHO ซึ่งเป็นเทคนิคการสร้างแบบจำลองทางสถิติที่มีการใช้งานน้อยมาก แทนที่จะกังวลเกี่ยวกับการเบี่ยงเบนจากสมมติฐานของโมเดลจำลองความเบี่ยงเบนเหล่านั้น!
R
ก็อาจเป็นประโยชน์ต่อคุณในการอ่านคำตอบของฉันที่นี่: ทางเลือก ANOVA ทางเดียวสำหรับข้อมูลที่แตกต่างกันซึ่งอธิบายถึงปัญหาเหล่านี้