การคำนวณค่า p โดยใช้ bootstrap ด้วย R


28

ฉันใช้แพคเกจ "boot" เพื่อคำนวณค่าp-value bootstrapped แบบสองด้านโดยประมาณแต่ผลลัพธ์นั้นอยู่ห่างจาก p-value ของการใช้ t.test มากเกินไป ฉันไม่สามารถหาสิ่งที่ฉันทำผิดในรหัส R ของฉัน ใครช่วยได้โปรดให้คำแนะนำสำหรับเรื่องนี้กับฉัน

time = c(14,18,11,13,18,17,21,9,16,17,14,15,
         12,12,14,13,6,18,14,16,10,7,15,10)
group=c(rep(1:2, each=12))
sleep = data.frame(time, group)

require(boot)
diff = function(d1,i){
    d = d1[i,]
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

set.seed(1234)
b3 = boot(data = sleep, statistic = diff, R = 5000, strata=sleep$group)

pvalue = mean(abs(b3$t) > abs(b3$t0))
pvalue 

ค่า p bootstrapped แบบสองด้าน (pvalue) = 0.4804 แต่ค่า p-value แบบสองด้านของ t.test เท่ากับ 0.04342 ค่า p ทั้งสองมีค่าต่างกันประมาณ 11 เท่า สิ่งนี้จะเกิดขึ้นได้อย่างไร?


ทำไม b3 $ t0 จึงมีสองรายการ
ซีอาน

1
มันเป็นชื่อ!
Elvis

2
คุณกำลังคำนวณค่า -val อย่างไม่ถูกต้อง เอกสารบอกว่าเป็นสถิติที่สังเกตได้ไม่ใช่การแจกแจงแบบโมฆะตามที่แนะนำ คุณต้องหาค่าประมาณของการสุ่มตัวอย่าง dist-n ภายใต้ค่า Null ดูคำตอบของฉันสำหรับข้อมูลเพิ่มเติม ลองทำแบบทดสอบอคติที่ไม่ถูกต้อง t 0พีเสื้อ0mean(abs(b3$t0) < abs(b3$t-mean(b3$t)))
AdamO

คำตอบ:


31

คุณกำลังใช้ bootstrap เพื่อสร้างข้อมูลภายใต้การกระจายเชิงประจักษ์ของข้อมูลที่สังเกตได้ สิ่งนี้มีประโยชน์ในการให้ช่วงความมั่นใจกับความแตกต่างระหว่างสองวิธี:

> quantile(b3$t,c(0.025,0.975))
     2.5%     97.5% 
0.4166667 5.5833333 

ในการรับค่าคุณต้องสร้างพีชคณิตภายใต้สมมติฐานว่าง สามารถทำได้เช่นนี้พี

diff2 = function(d1,i){
    d = d1; 
    d$group <- d$group[i];  # randomly re-assign groups
    Mean= tapply(X=d$time, INDEX=d$group, mean)
    Diff = Mean[1]-Mean[2]
    Diff
}

> set.seed(1234)
> b4 = boot(data = sleep, statistic = diff2, R = 5000)
> mean(abs(b4$t) > abs(b4$t0))
[1] 0.046

ในโซลูชันนี้ขนาดของกลุ่มจะไม่คงที่คุณกำหนดกลุ่มแบบสุ่มให้กับแต่ละบุคคลโดยการบูทสแตรปจากชุดกลุ่มเริ่มต้น ดูเหมือนว่าเป็นเรื่องถูกต้องสำหรับฉัน แต่วิธีการแก้ปัญหาแบบดั้งเดิมคือการกำหนดจำนวนบุคคลของแต่ละกลุ่มดังนั้นคุณเพียงแค่เปลี่ยนกลุ่มแทนที่จะใช้วิธีบู๊ต (นี่คือแรงบันดาลใจจากการออกแบบการทดลอง ):

> R <- 10000; d <- sleep
> b5 <- numeric(R); for(i in 1:R) { 
+    d$group <- sample(d$group, length(d$group)); 
+    b5[i] <- mean(d$time[d$group==1])-mean(d$time[d$group==2]); 
+ }
> mean(abs(b5) > 3)
[1] 0.0372

5
นี่คือเทคนิคการทดสอบการเปลี่ยนรูปไม่ใช่ค่า bootstrap p-value
AdamO

@AdamO ฉันยอมรับว่าสิ่งที่นำเสนอในคำตอบนี้คือการทดสอบการเปลี่ยนแปลง (และตัวแปรที่เปลี่ยนแปลงเล็กน้อย); นี่เป็นเพราะในระหว่างการ resampling กลุ่มจะรวมกัน ในทางตรงกันข้ามในการทดสอบบน bootstrap ค่าสำหรับแต่ละกลุ่มควรถูกสุ่มตัวอย่างโดยใช้ข้อมูลสำหรับกลุ่มเดียวกันนั้นเท่านั้น นี่คือหนึ่งในคำตอบที่อธิบายวิธีการทำมันstats.stackexchange.com/a/187630/28666
อะมีบาพูดว่า Reinstate Monica

@ amoeba ฉันคิดว่าคำตอบที่คุณลิงค์นั้นเป็นแบบทดสอบการเปลี่ยนแปลงที่เกี่ยวข้องกับ bootstrap เพียงตราบเท่าที่พวกเขาเกี่ยวข้องกับการ resampling สามารถรายงานได้อย่างสมบูรณ์แบบ แต่สำหรับการรายงานเป็นสองวิธีที่ใช้งานอยู่ bootstrap ที่ไม่ใช่พารามิเตอร์ไม่สามารถสร้างข้อมูลภายใต้สมมติฐานว่าง ดูคำตอบของฉันสำหรับวิธีสร้างค่า p จากการกระจาย bootstrap
AdamO

@AdamO ฉันเดาว่ามันเป็นคำถามของคำศัพท์ แต่ฉันไม่เห็นว่าขั้นตอนที่อธิบายไว้ในคำตอบที่เชื่อมโยงสามารถเรียกว่าการทดสอบ "การเปลี่ยนแปลง" เพราะไม่มีสิ่งใดถูกเปลี่ยนแปลงที่นั่น: ค่าที่ถูกเปลี่ยนสำหรับแต่ละกลุ่มถูกสร้างขึ้นโดยใช้ข้อมูลจาก กลุ่มเท่านั้น
อะมีบาพูดว่า Reinstate Monica

1
เอลวิสฉันคิดว่าโค้ดแรกในคำตอบของคุณคือการทดสอบการเรียงสับเปลี่ยน เมื่อคุณสุ่มตัวอย่างคุณรวมกลุ่มเข้าด้วยกัน! นี่คือสิ่งที่กำหนดการทดสอบการเปลี่ยนรูป
อะมีบาพูดว่า Reinstate Monica

25

คำตอบของ Elvis นั้นขึ้นอยู่กับวิธีเรียงสับเปลี่ยน แต่ในความคิดของฉันมันไม่ได้บอกชัดเจนว่าเกิดอะไรขึ้นกับวิธีบูตสแตรปดั้งเดิม ให้ฉันพูดถึงวิธีการแก้ปัญหาตาม bootstrap

ปัญหาที่สำคัญของการจำลองแบบดั้งเดิมของคุณคือ bootstrap จะให้การแจกแจงสถิติการทดสอบจริง อย่างไรก็ตามเมื่อคำนวณ p-value คุณจะต้องเปรียบเทียบค่าที่ได้รับของสถิติการทดสอบกับการแจกแจงภายใต้ H0 นั่นคือไม่ใช่การกระจายที่แท้จริง!

[ขอให้ชัดเจน ตัวอย่างเช่นเป็นที่ทราบกันดีว่าสถิติการทดสอบ T ของการทดสอบแบบคลาสสิคนั้นมีการแจกแจงแบบ "กลาง" แบบคลาสสิกภายใต้ H0 และการแจกแจงแบบไม่มีศูนย์กลางโดยทั่วไป อย่างไรก็ตามทุกคนคุ้นเคยกับความจริงที่ว่าค่าที่สังเกตได้ของ T นั้นถูกนำไปเปรียบเทียบกับการแจกแจงแบบที "ส่วนกลาง" แบบดั้งเดิมนั่นคือเราไม่ได้พยายามที่จะได้การแจกแจงแบบ t [noncenral] จริงเพื่อเปรียบเทียบกับ T]

p-value 0.4804 ของคุณมีขนาดใหญ่มากเนื่องจากค่าที่สังเกตได้ "t0" ของค่าสถิติการทดสอบหมายถึง [1] - หมายถึง [2] อยู่ใกล้กับศูนย์กลางของตัวอย่างที่ถูก bootstrapped "t" มันเป็นเรื่องธรรมดาและมักจะเป็นเช่นนั้นเสมอ (เช่นโดยไม่คำนึงถึงความถูกต้องของ H0] เนื่องจากตัวอย่าง "bootstrapped" t "เลียนแบบการกระจายตัวจริงของค่าเฉลี่ย [1] - หมายถึง [2] แต่ตามที่ระบุไว้ข้างต้น [และโดย Elvis] สิ่งที่คุณต้องการจริงๆคือการกระจายของ Mean [1] - หมายถึง [2] UNDER H0 เป็นที่ชัดเจนว่า

1) ภายใต้ H0 การแจกแจงค่าเฉลี่ย [1] - หมายถึง [2] จะอยู่กึ่งกลางรอบ 0

2) รูปร่างไม่ขึ้นอยู่กับความถูกต้องของ H0

จุดสองจุดเหล่านี้บอกเป็นนัยว่าการกระจายของค่าเฉลี่ย [1] - หมายถึง [2] ภายใต้ H0 สามารถเลียนแบบตัวอย่าง bootstrapped ตัวอย่าง "t" SHIFTED เพื่อให้อยู่กึ่งกลางรอบ 0 ใน R:

b3.under.H0 <- b3$t - mean(b3$t)

และค่า p ที่สอดคล้องกันจะเป็น:

mean(abs(b3.under.H0) > abs(b3$t0))

ซึ่งให้ค่า "ดีมาก" ที่ 0.0232 :-)

ให้ฉันทราบว่าจุด "2)" ที่กล่าวถึงข้างต้นเรียกว่า "การแปลความสมดุล" ของสถิติการทดสอบและไม่จำเป็นต้องถือโดยทั่วไป! เช่นสำหรับสถิติการทดสอบบางอย่างการขยับของ bootstrapped "t" ไม่ได้ให้การประมาณการที่ถูกต้องของการกระจายตัวของสถิติการทดสอบภายใต้ HO! ดูการสนทนานี้และโดยเฉพาะอย่างยิ่งคำตอบของ P. Dalgaard: http://tolstoy.newcastle.edu.au/R/e6/help/09/04/11096.html

ปัญหาการทดสอบของคุณให้ผลการแจกแจงสมมาตรอย่างสมบูรณ์ของสถิติการทดสอบ แต่โปรดจำไว้ว่ามีปัญหาบางอย่างในการรับค่า p สองค่าในกรณีที่การแจกแจงเบ้าแบบกระจายของสถิติการทดสอบ อ่านลิงค์ด้านบนอีกครั้ง

[และในที่สุดฉันจะใช้การทดสอบการเปลี่ยนรูปแบบ "บริสุทธิ์" ในสถานการณ์ของคุณ เช่นครึ่งหลังของคำตอบของ Elvis :-)]


17

มีวิธีการมากมายในการคำนวณ bootstrap CIs และค่า p ปัญหาหลักคือมันเป็นไปไม่ได้สำหรับ bootstrap เพื่อสร้างข้อมูลภายใต้สมมติฐานว่าง การทดสอบการเปลี่ยนรูปเป็นทางเลือกใหม่สำหรับการทดสอบซ้ำ ในการใช้ bootstrap ที่เหมาะสมคุณต้องทำการตั้งสมมติฐานเกี่ยวกับการกระจายตัวตัวอย่างของสถิติการทดสอบ

β0* * * *=β^-β^* * * *β0* * * *=β^* * * *-β^

bootstrap ปกติ

วิธีการหนึ่งคือbootstrap ปกติที่คุณใช้ค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานของการกระจาย bootstrap คำนวณการแจกแจงการสุ่มตัวอย่างภายใต้ null โดยเลื่อนการแจกแจงและใช้เปอร์เซนต์ปกติจากการแจกแจง null ที่จุดของการประเมินในตัวอย่าง bootstrap ดั้งเดิม . นี่เป็นวิธีการที่เหมาะสมเมื่อการกระจาย bootstrap เป็นปกติการตรวจสอบด้วยภาพมักจะเพียงพอที่นี่ ผลลัพธ์ที่ใช้วิธีนี้มักจะใกล้เคียงกับความสมบูรณ์หรือการประมาณค่าความผิดพลาดแบบแซนด์วิชซึ่งมีความทนทานต่อความแตกต่างของ heteroscedasticity และ / หรือข้อจำกัดความแปรปรวนตัวอย่าง จำกัด ข้อสันนิษฐานของสถิติการทดสอบปกติเป็นเงื่อนไขที่ดีกว่าของสมมติฐานในการทดสอบบู๊ตสแตรปถัดไปที่ฉันจะกล่าวถึง

บูตสแตรปเปอร์ไทล์

F0* * * *2×นาที(F0* * * *(β^),1-F0* * * *(β^))

bootstrap ที่ได้รับการศึกษา

พี

ตัวอย่างการเขียนโปรแกรม

ตัวอย่างเช่นฉันจะใช้cityข้อมูลในแพคเกจ bootstrap ช่วงความเชื่อมั่น bootstrap คำนวณด้วยรหัสนี้:

ratio <- function(d, w) sum(d$x * w)/sum(d$u * w)
city.boot <- boot(city, ratio, R = 999, stype = "w", sim = "ordinary")
boot.ci(city.boot, conf = c(0.90, 0.95),
        type = c("norm", "basic", "perc", "bca"))

และสร้างผลลัพธ์นี้:

BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 999 bootstrap replicates

CALL : 
boot.ci(boot.out = city.boot, conf = c(0.9, 0.95), type = c("norm", 
    "basic", "perc", "bca"))

Intervals : 
Level      Normal              Basic         
90%   ( 1.111,  1.837 )   ( 1.030,  1.750 )   
95%   ( 1.042,  1.906 )   ( 0.895,  1.790 )  

Level     Percentile            BCa          
90%   ( 1.291,  2.011 )   ( 1.292,  2.023 )   
95%   ( 1.251,  2.146 )   ( 1.255,  2.155 )  
Calculations and Intervals on Original Scale

95% CI สำหรับ bootstrap ปกติได้มาจากการคำนวณ:

with(city.boot, 2*t0 - mean(t) + qnorm(c(0.025, 0.975)) %o% sqrt(var(t)[1,1]))

จึงได้รับค่า p:

> with(city.boot, pnorm(abs((2*t0 - mean(t) - 1) / sqrt(var(t)[1,1])), lower.tail=F)*2)
[1] 0.0315

ซึ่งยอมรับว่า 95% ปกติ CI ไม่รวมค่าอัตราส่วนโมฆะของ 1

CI เปอร์เซ็นไทล์ได้มา (มีความแตกต่างเนื่องจากวิธีการสำหรับความสัมพันธ์):

quantile(city.boot$t, c(0.025, 0.975))

และ p-value สำหรับ bootstrap เปอร์เซ็นไทล์คือ:

cvs <- quantile(city.boot$t0 - city.boot$t + 1, c(0.025, 0.975))
mean(city.boot$t > cvs[1] & city.boot$t < cvs[2])

ให้ ap ของ 0.035 ซึ่งเห็นด้วยกับช่วงความเชื่อมั่นในแง่ของการยกเว้น 1 จากค่า โดยทั่วไปเราไม่สามารถสังเกตได้ว่าในขณะที่ความกว้างของเปอร์เซ็นไทล์ CI นั้นกว้างเกือบเท่ากับ CI ปกติและเปอร์เซ็นไทล์ CI นั้นอยู่ไกลจากโมฆะที่เปอร์เซ็นไทล์ CI ควรให้ค่า p ต่ำกว่า นี่เป็นเพราะรูปร่างของการแจกแจงตัวอย่างที่อ้างอิง CI สำหรับวิธีเปอร์เซ็นต์ไทล์นั้นไม่ปกติ


มันเป็นคำตอบที่น่าสนใจมาก @AdamO แต่คุณสามารถยกตัวอย่างบางส่วนได้หรือไม่? บน R คุณสามารถใช้ฟังก์ชั่นboot.ciและใช้อาร์กิวเมนต์ "type" เพื่อเลือก CI ที่นักเรียนได้รับ (คุณสามารถเลือก BCA CI) อย่างไรก็ตามคุณจะคำนวณค่า p ได้อย่างไร คุณใช้ประมาณการหรือสถิติทดสอบหรือไม่ ฉันมีคำถามที่คล้ายกันซึ่งคำตอบจะได้รับการชื่นชมอย่างมาก
Kevin Zarca

1
+1 สำหรับคำอธิบายที่ชัดเจนเกี่ยวกับประโยชน์ของ bootstrap ที่ทำให้เป็นนักเรียน
eric_kernfeld

@KevinOunet ฉันให้สองตัวอย่างของการจำลองค่า p จาก CIs ในแพ็คเกจการบูต สิ่งนี้ช่วยได้ไหม?
AdamO

1
ขอบคุณ @AdamO ที่ช่วยได้แน่นอน! คุณสามารถให้ตัวอย่างสุดท้ายสำหรับ bootstrap studentized?
Kevin Zarca
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.