สมมติว่าฉันมีข้อมูลที่มีสองกลุ่มอิสระ:
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)
จะเห็นว่าขนาดของกลุ่มตัวอย่างต่อกลุ่มจะลำเอียงที่G1 มี 6สังเกตและG2 มี 22 ANOVA ดั้งเดิมชี้ให้เห็นว่ากลุ่มมีวิธีการที่แตกต่างกันเมื่อค่าวิกฤตถูกตั้งค่าเป็น 0.05 (ค่า p คือ0.0044 )
summary (aov (lengths~group, data = lengths))
เนื่องจากจุดมุ่งหมายของฉันคือการเปรียบเทียบความแตกต่างของค่าเฉลี่ยข้อมูลตัวอย่างที่ไม่สมดุลและขนาดเล็กอาจให้ผลลัพธ์ที่ไม่เหมาะสมด้วยวิธีการแบบดั้งเดิม ดังนั้นฉันต้องการทำการทดสอบการเปลี่ยนแปลงและ bootstrap
การทดสอบ PERMUTATION
สมมติฐาน Null (H0) ระบุว่าค่าเฉลี่ยของกลุ่มเหมือนกัน ข้อสันนิษฐานในการทดสอบการเปลี่ยนแปลงนี้มีการพิสูจน์ด้วยการรวมกลุ่มเป็นตัวอย่างเดียว สิ่งนี้ทำให้มั่นใจได้ว่าตัวอย่างสำหรับสองกลุ่มนั้นมาจากการแจกแจงที่เหมือนกัน โดยการสุ่มตัวอย่างซ้ำ ๆ (หรือแม่นยำยิ่งขึ้น - reshuffling) จากข้อมูล pooled การสังเกตจะถูกจัดสรรใหม่ (สับ) กับตัวอย่างในวิธีการใหม่และคำนวณสถิติการทดสอบ การดำเนินการ n ครั้งนี้จะให้การกระจายตัวอย่างของสถิติการทดสอบภายใต้สมมติฐานที่ H0 คือ TRUE ในตอนท้ายภายใต้ H0 ค่า p คือความน่าจะเป็นที่สถิติทดสอบเท่ากับหรือสูงกว่าค่าที่สังเกตได้
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)
p-value รายงานของการทดสอบการเปลี่ยนแปลงเป็น0.0053 ตกลงถ้าฉันทำอย่างถูกต้องการเรียงสับเปลี่ยนและพารามิเตอร์ ANOVA ให้ผลลัพธ์เกือบเหมือนกัน
บูต
ก่อนอื่นฉันทราบว่า bootstrap ไม่สามารถช่วยได้เมื่อขนาดตัวอย่างเล็กเกินไป โพสต์นี้แสดงให้เห็นว่ามันอาจจะยิ่งเลวร้ายลงและทำให้เข้าใจผิด นอกจากนี้ข้อที่สองเน้นว่าการทดสอบการเปลี่ยนแปลงโดยทั่วไปดีกว่า bootstrapเมื่อการทดสอบสมมติฐานเป็นเป้าหมายหลัก อย่างไรก็ตามโพสต์ที่ยอดเยี่ยมนี้พูดถึงความแตกต่างที่สำคัญระหว่างวิธีการที่ใช้คอมพิวเตอร์มาก ๆ อย่างไรก็ตามที่นี่ฉันต้องการเพิ่ม (ฉันเชื่อ) คำถามอื่น
ให้ฉันแนะนำวิธี bootstrap ที่พบบ่อยที่สุดก่อน (Bootstrap1: resampling ภายในกลุ่ม pooled ตัวอย่าง ):
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)
ค่า P ของบูตดำเนินการในลักษณะนี้เป็น0.005 แม้ว่ามันจะฟังดูสมเหตุสมผลและเกือบจะเหมือนกับการทดสอบความแปรปรวนแบบ Parametric และการเปลี่ยนแปลงการเปลี่ยนแปลงมันเหมาะสมหรือไม่ที่จะแสดงให้เห็นว่า H0 ใน bootstrap นี้บนพื้นฐานที่เราเพิ่งรวบรวมตัวอย่างจากที่เราวาดตัวอย่างต่อมา?
แนวทางที่แตกต่างฉันพบในเอกสารทางวิทยาศาสตร์หลายฉบับ โดยเฉพาะฉันเห็นว่านักวิจัยแก้ไขข้อมูลเพื่อให้ตรงกับ H0 ก่อน bootstrap เมื่อค้นหารอบ ๆ ฉันพบโพสต์ที่น่าสนใจมากใน CVโดยที่@ jan.sอธิบายผลลัพธ์ที่ผิดปกติของ bootstrap ในคำถามโพสต์ที่มีจุดประสงค์เพื่อเปรียบเทียบสองวิธี อย่างไรก็ตามในการโพสต์นั้นจะไม่ครอบคลุมถึงวิธีการ bootstrap เมื่อมีการแก้ไขข้อมูลก่อน bootstrap วิธีการที่ข้อมูลถูกแก้ไขก่อนบูตสแตรปมีลักษณะดังนี้:
- H0 ระบุว่าค่าเฉลี่ยของสองกลุ่มเหมือนกัน
- H0 ถือเป็นจริงถ้าเราลบการสังเกตแต่ละรายการจากค่าเฉลี่ยของกลุ่มตัวอย่าง
ในกรณีนี้การปรับเปลี่ยนข้อมูลควรมีผลต่อความหมายของกลุ่มและดังนั้นจึงแตกต่างกัน แต่ไม่เปลี่ยนแปลงในกลุ่ม (และระหว่าง)
- แก้ไขข้อมูลจะเป็นพื้นฐานสำหรับการบูตต่อไปด้วยประการที่สุ่มตัวอย่างจะดำเนินการในแต่ละกลุ่มแยกต่างหาก
- ความแตกต่างระหว่างค่าเฉลี่ย bootstrapped ของ g1 และ g2 นั้นถูกคำนวณและเปรียบเทียบกับความแตกต่างระหว่างกลุ่ม
- สัดส่วนของค่าที่เท่ากันหรือมากเกินกว่าที่สังเกตได้หนึ่งหารด้วยจำนวนการทำซ้ำจะให้ค่า p
นี่คือรหัส (Bootstrap2: การสุ่มตัวอย่างใหม่ภายในกลุ่มหลังจากการปรับเปลี่ยนที่ H0 คือ 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 ที่ทำเช่นนี้จะให้ค่า p 0.514ซึ่งแตกต่างอย่างมากเมื่อเทียบกับการทดสอบก่อนหน้านี้ ฉันเชื่อว่าสิ่งนี้จะต้องจัดการกับคำอธิบายของ @jan.sแต่ฉันไม่สามารถหาได้ว่ากุญแจอยู่ที่ไหน ...
H0 <- pool - mean (pool)
วิธีที่จะทำให้มันเป็นหนึ่งในการทำงานนี้: H0 <- c(g1.lengths - mean(g1.lengths), g2.lengths - mean(g2.lengths))
มันต้องถูกแทนที่ด้วย จากนั้นคุณจะได้รับค่า p-0.0023 (นี่คือสิ่งเดียวกับที่เซนิตอธิบายไว้ในคำตอบของเขา) นี่คือทั้งหมดที่มีให้มันเป็นเพียงข้อบกพร่องง่ายๆในโค้ด CC ถึง @MichaelChernick