Thực sự không khó để xử lý sự không đồng nhất trong các mô hình tuyến tính đơn giản (ví dụ: các mô hình giống như ANOVA một hoặc hai chiều).
Sự mạnh mẽ của ANOVA
Đầu tiên, như những người khác lưu ý, ANOVA mạnh mẽ đến mức đáng kinh ngạc so với giả định về phương sai bằng nhau, đặc biệt là nếu bạn có dữ liệu cân bằng (số lượng quan sát bằng nhau trong mỗi nhóm). Các thử nghiệm sơ bộ về phương sai bằng nhau, mặt khác, không phải (mặc dù thử nghiệm của Levene tốt hơn nhiều so với F -test thường được dạy trong sách giáo khoa). Như George Box đã nói:
Để thực hiện thử nghiệm sơ bộ về phương sai thay vì đưa ra biển trong một chiếc thuyền chèo để tìm hiểu xem điều kiện có đủ bình tĩnh để một tàu biển rời cảng không!
Mặc dù ANOVA rất mạnh mẽ, vì rất dễ tính đến tính không đồng nhất, nhưng có rất ít lý do để không làm như vậy.
Xét nghiệm không tham số
Nếu bạn thực sự quan tâm đến sự khác biệt về phương tiện , các bài kiểm tra không tham số (ví dụ: bài kiểm tra Kruskal Kiếm Wallis) thực sự không được sử dụng. Họ kiểm tra sự khác biệt giữa các nhóm, nhưng họ không kiểm tra sự khác biệt chung về phương tiện.
Dữ liệu mẫu
Chúng ta hãy tạo một ví dụ đơn giản về dữ liệu mà người ta muốn sử dụng ANOVA, nhưng giả định về phương sai bằng nhau là không đúng.
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)
Chúng tôi có ba nhóm, với sự khác biệt (rõ ràng) về cả phương tiện và phương sai:
stripchart(x ~ group, data=d)
ANOVA
Không có gì đáng ngạc nhiên, một ANOVA bình thường xử lý việc này khá tốt:
> 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
Vậy, nhóm nào khác nhau? Hãy sử dụng phương pháp HSD của 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
Với giá trị P là 0,26, chúng tôi không thể yêu cầu bất kỳ sự khác biệt (về phương tiện) giữa nhóm A và B. Và ngay cả khi chúng tôi không tính đến việc chúng tôi đã thực hiện ba so sánh, chúng tôi sẽ không nhận được P thấp - giá trị ( 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
Tại sao vậy? Dựa trên cốt truyện, có là một sự khác biệt khá rõ ràng. Lý do là ANOVA giả định phương sai bằng nhau trong mỗi nhóm và ước tính độ lệch chuẩn chung là 2,77 (được hiển thị là 'Lỗi tiêu chuẩn dư' trong summary.lm
bảng hoặc bạn có thể lấy nó bằng cách lấy căn bậc hai của bình phương trung bình còn lại (7,66) trong bảng ANOVA).
Nhưng nhóm A có độ lệch chuẩn (dân số) là 1, và sự đánh giá quá cao này là 2,77 khiến cho (không cần thiết) có được kết quả có ý nghĩa thống kê, nghĩa là chúng tôi có một bài kiểm tra với (quá) công suất thấp.
"ANOVA" với phương sai không bằng nhau
Vì vậy, làm thế nào để phù hợp với một mô hình thích hợp, một mô hình có tính đến sự khác biệt về phương sai? Thật dễ dàng trong 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
Vì vậy, nếu bạn muốn chạy một 'ANOVA' một chiều đơn giản trong R mà không giả sử phương sai bằng nhau, hãy sử dụng chức năng này. Về cơ bản, đây là phần mở rộng của (Welch) t.test()
cho hai mẫu có phương sai không bằng nhau.
Thật không may, nó không hoạt động với TukeyHSD()
(hoặc hầu hết các chức năng khác mà bạn sử dụng trên aov
các đối tượng), vì vậy ngay cả khi chúng tôi khá chắc chắn có được sự khác biệt nhóm, chúng tôi không biết nơi họ đang có.
Mô hình hóa sự không đồng nhất
Giải pháp tốt nhất là mô hình hóa các phương sai một cách rõ ràng. Và nó rất dễ dàng trong 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
Vẫn có sự khác biệt đáng kể, tất nhiên. Nhưng giờ đây, sự khác biệt giữa nhóm A và B cũng đã trở nên có ý nghĩa tĩnh ( 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
Vì vậy, sử dụng một mô hình thích hợp sẽ giúp! Cũng lưu ý rằng chúng tôi nhận được ước tính về độ lệch chuẩn (tương đối). Độ lệch chuẩn ước tính cho nhóm A có thể được tìm thấy ở dưới cùng, kết quả, 1,02. Độ lệch chuẩn ước tính của nhóm B là 2,44 lần, hoặc 2,48 và độ lệch chuẩn ước tính của nhóm C là 3,97 (loại intervals(mod.gls)
để có khoảng tin cậy cho độ lệch chuẩn tương đối của nhóm B và C).
Sửa lỗi cho nhiều thử nghiệm
Tuy nhiên, chúng tôi thực sự nên sửa cho nhiều thử nghiệm. Điều này thật dễ dàng khi sử dụng thư viện 'multcomp'. Thật không may, nó không có hỗ trợ tích hợp cho các đối tượng 'gls', vì vậy trước tiên chúng ta sẽ phải thêm một số chức năng trợ giúp:
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),...)
Bây giờ hãy đi làm:
> 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 *
Vẫn có sự khác biệt có ý nghĩa thống kê giữa nhóm A và nhóm B! Và chúng tôi thậm chí có thể có được khoảng tin cậy (đồng thời) cho sự khác biệt giữa các nhóm có nghĩa là:
> 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
Sử dụng một mô hình chính xác (ở đây chính xác), chúng tôi có thể tin tưởng những kết quả này!
Lưu ý rằng đối với ví dụ đơn giản này, dữ liệu cho nhóm C không thực sự thêm bất kỳ thông tin nào về sự khác biệt giữa nhóm A và B, vì chúng tôi mô hình cả phương tiện và độ lệch chuẩn cho từng nhóm. Chúng ta có thể vừa sử dụng các t- tests cặp đã sửa cho nhiều phép so sánh:
> 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
Tuy nhiên, đối với các mô hình phức tạp hơn, ví dụ: mô hình hai chiều hoặc mô hình tuyến tính có nhiều yếu tố dự đoán, sử dụng GLS (bình phương tối thiểu tổng quát) và mô hình hóa rõ ràng các hàm phương sai là giải pháp tốt nhất.
Và hàm phương sai không chỉ đơn giản là một hằng số khác nhau trong mỗi nhóm; chúng ta có thể áp đặt cấu trúc lên nó. Ví dụ, chúng ta có thể mô hình phương sai là công suất trung bình của mỗi nhóm (và do đó chỉ cần ước tính một tham số, số mũ) hoặc có thể là logarit của một trong các yếu tố dự đoán trong mô hình. Tất cả điều này rất dễ dàng với GLS (và gls()
trong R).
Bình phương tối thiểu tổng quát là IMHO một kỹ thuật mô hình thống kê rất ít được sử dụng. Thay vì lo lắng về những sai lệch so với các giả định của mô hình , hãy mô hình hóa những sai lệch đó!
R
, nó có thể có lợi cho bạn khi đọc câu trả lời của tôi ở đây: Các lựa chọn thay thế cho ANOVA một chiều cho dữ liệu không đồng nhất , trong đó thảo luận về một số vấn đề này.