Giả sử rằng tôi có dữ liệu với hai nhóm độc lập:
g1.lengths <- c (112.64, 97.10, 84.18, 106.96, 98.42, 101.66)
g2.lengths <- c (84.44, 82.10, 83.26, 81.02, 81.86, 86.80,
85.84, 97.08, 79.64, 83.32, 91.04, 85.92,
73.52, 85.58, 97.70, 89.72, 88.92, 103.72,
105.02, 99.48, 89.50, 81.74)
group = rep (c ("g1", "g2"), c (length (g1.lengths), length (g2.lengths)))
lengths = data.frame( lengths = c(g1.lengths, g2.lengths), group)
Rõ ràng là kích thước mẫu trên mỗi nhóm bị sai lệch trong đó g1 có 6 quan sát và g2 có 22 . ANOVA truyền thống gợi ý rằng các nhóm có các phương tiện khác nhau khi giá trị tới hạn được đặt thành 0,05 (giá trị p là 0,0044 ).
summary (aov (lengths~group, data = lengths))
Cho rằng mục đích của tôi là so sánh sự khác biệt trung bình, dữ liệu được lấy mẫu nhỏ và không cân bằng như vậy có thể cho kết quả không phù hợp với phương pháp truyền thống. Do đó, tôi muốn thực hiện kiểm tra hoán vị và bootstrap.
KIỂM TRA XÁC NHẬN
Giả thuyết Null (H0) nói rằng phương tiện của nhóm là như nhau. Giả định này trong thử nghiệm hoán vị được chứng minh bằng cách gộp các nhóm thành một mẫu. Điều này đảm bảo rằng các mẫu cho hai nhóm được rút ra từ phân phối giống hệt nhau. Bằng cách lấy mẫu lặp lại (hoặc chính xác hơn - chia sẻ lại) từ dữ liệu được gộp, các quan sát được phân bổ lại (xáo trộn) cho các mẫu theo cách mới và tính toán thống kê thử nghiệm. Thực hiện lần này n lần, sẽ đưa ra phân phối lấy mẫu các thống kê kiểm tra theo giả định trong đó H0 là TRUE. Cuối cùng, dưới giá trị H0, p là xác suất mà thống kê kiểm tra bằng hoặc vượt quá giá trị quan sát được.
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.p <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.p <- NULL
set.seed (5)
for (i in 1 : iterations) {
resample <- sample (c(1:length (pool)), length(pool))
g1.perm = pool[resample][1 : s.size.g1]
g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
sampl.dist.p[i] = mean (g1.perm) - mean (g2.perm)
}
p.permute <- (sum (abs (sampl.dist.p) >= abs(obs.diff.p)) + 1)/ (iterations+1)
Báo cáo giá trị p của kiểm tra hoán vị là 0,0053 . OK, nếu tôi làm đúng, hoán vị và ANOVA tham số cho kết quả gần như giống hệt nhau.
BOOTSTRAP
Trước hết, tôi biết rằng bootstrap không thể giúp khi kích thước mẫu quá nhỏ. Bài đăng này cho thấy nó có thể còn tồi tệ hơn và gây hiểu lầm . Ngoài ra, điều thứ hai nhấn mạnh rằng kiểm tra hoán vị thường tốt hơn bootstrap khi kiểm tra giả thuyết là mục đích chính. Tuy nhiên, bài đăng tuyệt vời này giải quyết sự khác biệt quan trọng giữa các phương pháp sử dụng nhiều máy tính. Tuy nhiên, ở đây tôi muốn đưa ra (tôi tin) một câu hỏi khác.
Trước tiên, hãy để tôi giới thiệu cách tiếp cận bootstrap phổ biến nhất (Bootstrap1: lấy mẫu lại trong mẫu gộp ):
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.b1 <- mean (g1.lengths) - mean (g2.lengths)
iterations <- 10000
sampl.dist.b1 <- NULL
set.seed (5)
for (i in 1 : iterations) {
resample <- sample (c(1:length (pool)), length(pool), replace = TRUE)
# "replace = TRUE" is the only difference between bootstrap and permutations
g1.perm = pool[resample][1 : s.size.g1]
g2.perm = pool[resample][(s.size.g1+1) : length(pool)]
sampl.dist.b1[i] = mean (g1.perm) - mean (g2.perm)
}
p.boot1 <- (sum (abs (sampl.dist.b1) >= obs.diff.b1) + 1)/ (iterations+1)
Giá trị P của bootstrap được thực hiện theo cách này là 0,005 . Mặc dù điều này nghe có vẻ hợp lý và gần như giống hệt với ANOVA tham số và phép thử hoán vị, liệu có phù hợp để biện minh cho H0 trong bootstrap này trên cơ sở chúng ta chỉ gộp các mẫu mà chúng ta đã rút ra các mẫu tiếp theo không?
Cách tiếp cận khác nhau tôi tìm thấy trong một số bài báo khoa học. Cụ thể, tôi thấy rằng các nhà nghiên cứu sửa đổi dữ liệu để đáp ứng H0 trước khi bootstrap. Tìm kiếm xung quanh, tôi đã tìm thấy bài đăng rất thú vị trong CV , nơi @ jan.s đã giải thích kết quả bất thường của bootstrap trong câu hỏi bài viết nhằm mục đích so sánh hai phương tiện. Tuy nhiên, trong bài đăng đó không đề cập đến cách thực hiện bootstrap khi dữ liệu được sửa đổi trước khi bootstrap. Cách tiếp cận nơi dữ liệu được sửa đổi trước khi bootstrap trông như thế này:
- H0 nói rằng phương tiện của hai nhóm là như nhau
- H0 đúng nếu chúng ta trừ các quan sát riêng lẻ khỏi giá trị trung bình của mẫu gộp
Trong trường hợp này, việc sửa đổi dữ liệu sẽ ảnh hưởng đến các nhóm có nghĩa là, và do đó, sự khác biệt của nó, nhưng không thay đổi trong các nhóm (và giữa).
- Dữ liệu được sửa đổi sẽ là cơ sở cho bootstrap tiếp theo, với sự cẩn thận rằng việc lấy mẫu được thực hiện trong từng nhóm riêng biệt .
- Sự khác biệt giữa trung bình bootstrapping của g1 và g2 được tính toán và so sánh với sự khác biệt quan sát (không sửa đổi) giữa các nhóm.
- Tỷ lệ các giá trị cực trị bằng hoặc nhiều hơn so với quan sát được chia cho số lần lặp sẽ cho giá trị p.
Đây là mã (Bootstrap2: lấy mẫu lại trong các nhóm sau khi sửa đổi rằng H0 là TRUE ):
s.size.g1 <- length (g1.lengths)
s.size.g2 <- length (g2.lengths)
pool <- lengths$lengths
obs.diff.b2 <- mean (g1.lengths) - mean (g2.lengths)
# make H0 to be true (no difference between means of two groups)
H0 <- pool - mean (pool)
# g1 from H0
g1.H0 <- H0[1:s.size.g1]
# g2 from H0
g2.H0 <- H0[(s.size.g1+1):length(pool)]
iterations <- 10000
sampl.dist.b2 <- NULL
set.seed (5)
for (i in 1 : iterations) {
# Sample with replacement in g1
g1.boot = sample (g1.H0, replace = T)
# Sample with replacement in g2
g2.boot = sample (g2.H0, replace = T)
# bootstrapped difference
sampl.dist.b2[i] <- mean (g1.boot) - mean (g2.boot)
}
p.boot2 <- (sum (abs (sampl.dist.b2) >= obs.diff.b2) + 1)/ (iterations+1)
Bootstrap được thực hiện như vậy sẽ cho giá trị p là 0,514 , rất khác so với các thử nghiệm trước đó. Tôi tin rằng điều này phải giải quyết với lời giải thích của @ jan.s ' , nhưng tôi không thể tìm ra đâu là chìa khóa ...
H0 <- pool - mean (pool)
. Nó cần phải được thay thế bằng H0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths))
. Sau đó, bạn sẽ nhận được giá trị p là 0,0023. (Đây là điều tương tự mà Zenit đã giải thích trong câu trả lời của anh ấy.) Đây là tất cả những gì có, chỉ là một lỗi đơn giản trong mã. CC gửi tới @MichaelCécick