ฉันสงสัยว่าทำไมการรวบรวมข้อมูลจนกว่าจะได้ผลลัพธ์ที่สำคัญ (เช่น ) ได้รับ (เช่นการแฮ็ค p) เพิ่มอัตราความผิดพลาด Type I หรือไม่
ฉันขอชื่นชมการR
สาธิตปรากฏการณ์นี้อย่างมาก
ฉันสงสัยว่าทำไมการรวบรวมข้อมูลจนกว่าจะได้ผลลัพธ์ที่สำคัญ (เช่น ) ได้รับ (เช่นการแฮ็ค p) เพิ่มอัตราความผิดพลาด Type I หรือไม่
ฉันขอชื่นชมการR
สาธิตปรากฏการณ์นี้อย่างมาก
คำตอบ:
ปัญหาคือคุณให้โอกาสตัวเองมากเกินไปที่จะผ่านการทดสอบ นี่เป็นเพียงเวอร์ชันแฟนซีของกล่องโต้ตอบนี้:
ฉันจะพลิกคุณเพื่อดูว่าใครจ่ายสำหรับอาหารค่ำ
ตกลงฉันเรียกหัว
หนูคุณชนะแล้ว ดีที่สุดสองในสาม
หากต้องการทำความเข้าใจกับสิ่งนี้ให้ดีขึ้นให้พิจารณาแบบจำลองที่เรียบง่าย แต่เป็นจริงของขั้นตอนต่อเนื่องนี้ สมมติว่าคุณจะเริ่มต้นด้วยการ "หนีคดี" ของจำนวนที่แน่นอนของการสังเกต แต่ยินดีที่จะยังคงอยู่ในการทดลองเพื่อให้ได้รับค่า p น้อยกว่า0.05สมมติฐานว่างคือการสังเกตแต่ละครั้งมาจากการแจกแจงแบบปกติมาตรฐาน (อิสระ) อีกทางเลือกหนึ่งคือมาจากการแจกแจงปกติความแปรปรวนของหน่วยด้วยค่าเฉลี่ยที่ไม่ใช่ศูนย์ สถิติการทดสอบจะเป็นค่าเฉลี่ยของทุกสังเกตหารด้วยข้อผิดพลาดมาตรฐานของพวกเขา{n} สำหรับการทดสอบสองด้านค่าที่สำคัญคือX ฉันX ฉัน n ˉ X 1 / √ 0.0250.975Zα=±1.96คะแนนร้อยละและของการแจกแจงแบบปกติมาตรฐาน,โดยประมาณ
นี่คือการทดสอบที่ดี --for การทดสอบเดียวกับขนาดของกลุ่มตัวอย่างคงที่nมีโอกาสในการปฏิเสธสมมติฐานว่างไม่ว่าอาจเป็นอะไร5 % n
ลองเปลี่ยนพีชคณิตเป็นพีชคณิตเป็นแบบทดสอบที่เท่ากันโดยอิงจากผลรวมของค่าทั้งหมด,S n = X 1 + X 2 + ⋯ + X n = n ˉ X
ดังนั้นข้อมูลจะ "สำคัญ" เมื่อ
นั่นคือ,
หากเราฉลาดเราจะลดความสูญเสียและยอมแพ้เมื่อเติบโตขึ้นมากและข้อมูลยังไม่ได้เข้าสู่ภูมิภาคที่สำคัญ
นี้อธิบายสุ่มเดิน S_nสูตรจำนวนจะสร้าง "รั้ว" โค้งหรือพาราโบลาโค้งรอบพล็อตของการเดินแบบสุ่ม : ผลลัพธ์คือ "สำคัญ" หากจุดใด ๆของการสุ่มเดินกระทบรั้ว ( 1 ) ( n , S n )
มันเป็นคุณสมบัติของการเดินแบบสุ่มว่าถ้าเรารอนานพอมีโอกาสมากที่ในบางจุดผลลัพธ์จะดูมีความสำคัญ
นี่คือการจำลองอิสระ 20 แบบจนถึงขีด จำกัดตัวอย่าง พวกเขาทุกคนเริ่มต้นการทดสอบที่ตัวอย่างที่จุดที่เราตรวจสอบว่าแต่ละจุดอยู่นอกอุปสรรคที่ได้รับการวาดตามสูตร(1)จากจุดที่การทดสอบทางสถิติเป็นครั้งแรก "สำคัญ" ข้อมูลจำลองจะเป็นสีแดงn = 30 ( 1 )
คุณสามารถดูว่าเกิดอะไรขึ้น: การเดินแบบสุ่มจะเพิ่มขึ้นเรื่อย ๆ เมื่อเพิ่มขึ้น อุปสรรคกำลังแพร่กระจายในอัตราเดียวกัน - แต่ไม่เร็วพอที่จะหลีกเลี่ยงการเดินสุ่ม
ใน 20% ของการจำลองเหล่านี้พบความแตกต่าง "สำคัญ" - มักจะค่อนข้างเร็ว - แม้ว่าในทุก ๆ คนสมมติฐานว่างจะถูกต้องอย่างแน่นอน! การรันการจำลองประเภทนี้มากขึ้นบ่งชี้ว่าขนาดการทดสอบจริงใกล้เคียงกับมากกว่าค่าที่คาดหวังของ : นั่นคือความตั้งใจของคุณที่จะมองหา "นัยสำคัญ" จนถึงขนาดตัวอย่างให้โอกาสในการปฏิเสธค่า Null แม้ว่าค่า Null จะเป็นจริงα = 5 % 5000 25 %
โปรดสังเกตว่าในทั้งสี่กรณี "สำคัญ" เมื่อการทดสอบดำเนินต่อไปข้อมูลหยุดดูอย่างมีนัยสำคัญในบางจุด ในชีวิตจริงผู้ทดลองที่หยุด แต่เช้ากำลังเสียโอกาสในการสังเกต "การสลับขั้ว" เช่นนั้น การเลือกนี้ผ่านอคติหยุดตัวเลือกผลลัพธ์
ในการทดสอบตามลำดับที่ซื่อสัตย์ต่อความดีอุปสรรคคือเส้น พวกมันแพร่กระจายเร็วกว่าสิ่งกีดขวางโค้งที่แสดงไว้ที่นี่
library(data.table)
library(ggplot2)
alpha <- 0.05 # Test size
n.sim <- 20 # Number of simulated experiments
n.buffer <- 5e3 # Maximum experiment length
i.min <- 30 # Initial number of observations
#
# Generate data.
#
set.seed(17)
X <- data.table(
n = rep(0:n.buffer, n.sim),
Iteration = rep(1:n.sim, each=n.buffer+1),
X = rnorm((1+n.buffer)*n.sim)
)
#
# Perform the testing.
#
Z.alpha <- -qnorm(alpha/2)
X[, Z := Z.alpha * sqrt(n)]
X[, S := c(0, cumsum(X))[-(n.buffer+1)], by=Iteration]
X[, Trigger := abs(S) >= Z & n >= i.min]
X[, Significant := cumsum(Trigger) > 0, by=Iteration]
#
# Plot the results.
#
ggplot(X, aes(n, S, group=Iteration)) +
geom_path(aes(n,Z)) + geom_path(aes(n,-Z)) +
geom_point(aes(color=!Significant), size=1/2) +
facet_wrap(~ Iteration)
ผู้ที่ยังใหม่กับการทดสอบสมมติฐานมักคิดว่าเมื่อค่า ap ต่ำกว่า. 05 การเพิ่มผู้เข้าร่วมมากขึ้นจะลดค่า p เท่านั้น แต่นี่ไม่เป็นความจริง ภายใต้สมมติฐานว่างค่า ap จะกระจายอย่างสม่ำเสมอระหว่าง 0 และ 1 และสามารถกระเด็นไปรอบ ๆ ได้เล็กน้อยในช่วงนั้น
ฉันได้จำลองข้อมูลบางอย่างใน R (ทักษะ R ของฉันค่อนข้างพื้นฐาน) ในการจำลองนี้ฉันรวบรวมจุดข้อมูล 5 จุดโดยแต่ละกลุ่มมีการสุ่มเลือกสมาชิกภาพกลุ่ม (0 หรือ 1) และแต่ละคนมีการวัดผลลัพธ์แบบสุ่มที่เลือก ~ N (0,1) เริ่มต้นที่ผู้เข้าร่วม 6 ฉันทำการทดสอบ t ทุกรอบซ้ำ
for (i in 6:150) {
df[i,1] = round(runif(1))
df[i,2] = rnorm(1)
p = t.test(df[ , 2] ~ df[ , 1], data = df)$p.value
df[i,3] = p
}
ค่า p อยู่ในรูปนี้ สังเกตว่าฉันพบผลลัพธ์ที่สำคัญเมื่อขนาดตัวอย่างประมาณ 70-75 ถ้าฉันหยุดอยู่ตรงนั้นฉันจะจบลงด้วยการเชื่อว่าการค้นพบของฉันมีความสำคัญเพราะฉันจะพลาดความจริงที่ว่าค่า p ของฉันเพิ่มขึ้นกลับมาพร้อมกับกลุ่มตัวอย่างที่มีขนาดใหญ่ขึ้น เนื่องจากฉันรู้ว่าประชากรทั้งสองมีค่าเฉลี่ย 0 จึงต้องเป็นค่าบวกผิด ๆ นี่เป็นปัญหาของการเพิ่มข้อมูลจนกว่า p <.05 หากคุณเพิ่มความประพฤติที่เพียงพอในการทดสอบ p ในที่สุดก็จะข้ามขีด จำกัด . 05 และคุณสามารถพบผลกระทบที่สำคัญคือชุดข้อมูลใด ๆ
R
รหัสของคุณไม่ได้ทำงานเลย
df
ก่อน (ควรเป็นขนาดสุดท้าย) เนื่องจากรหัสเริ่มเขียนที่แถว 6 ความหมาย (ซึ่งตรงกับข้อความของคำตอบ) คือ df มีอยู่แล้วกับ 5 แถวที่กรอกข้อมูลแล้วอาจมีบางสิ่งที่เป็นเช่นนี้: n150<-vector("numeric",150); df<-data.frame(gp=n150,val=n150,pval=n150); init<-1:5; df[init,1]<-c(0,1,0,1,0); df[init,2]<-rnorm(5)
(จากนั้นเรียกใช้โค้ดด้านบน) จากนั้นอาจ: plot(df$pv[6:150])
คำตอบนี้เกี่ยวข้องกับความน่าจะเป็นในการได้รับผลลัพธ์ที่ "มีนัยสำคัญ" และการกระจายเวลาไปยังกิจกรรมนี้ในแบบจำลองของ @ whuber
รหัส R:
# Fig 1
par(mfrow=c(1,2),mar=c(4,4,.5,.5))
set.seed(16)
n <- 20
npoints <- n*100 + 1
t <- seq(1,n,len=npoints)
subset <- 1:n*100-99
deltat <- c(1,diff(t))
z <- qnorm(.975)
s <- cumsum(rnorm(npoints,sd=sqrt(deltat)))
plot(t,s,type="l",ylim=c(-1,1)*z*sqrt(n),ylab="S(t)",col="grey")
points(t[subset],s[subset],pch="+")
curve(sqrt(t)*z,xname="t",add=TRUE)
curve(-sqrt(t)*z,xname="t",add=TRUE)
tau <- log(t)
y <- s/sqrt(t)
plot(tau,y,type="l",ylim=c(-2.5,2.5),col="grey",xlab=expression(tau),ylab=expression(Y(tau)))
points(tau[subset],y[subset],pch="+")
abline(h=c(-z,z))
# Fig 2
nmax <- 1e+3
nsim <- 1e+5
alpha <- .05
t <- numeric(nsim)
n <- 1:nmax
for (i in 1:nsim) {
s <- cumsum(rnorm(nmax))
t[i] <- which(abs(s) > qnorm(1-alpha/2)*sqrt(n))[1]
}
delta <- ifelse(is.na(t),0,1)
t[delta==0] <- nmax + 1
library(survival)
par(mfrow=c(1,1),mar=c(4,4,.5,.5))
plot(survfit(Surv(t,delta)~1),log="xy",xlab="t",ylab="P(T>t)",conf.int=FALSE)
curve((1-alpha)*exp(-.125*(log(x))),add=TRUE,col="red",from=1,to=nmax)
จะต้องมีการกล่าวว่าการอภิปรายข้างต้นสำหรับมุมมองโลกบ่อยครั้งที่หลายหลากมาจากโอกาสที่คุณให้ข้อมูลจะรุนแรงมากขึ้นไม่ได้มาจากโอกาสที่คุณให้ผลกระทบที่มีอยู่ สาเหตุที่แท้จริงของปัญหาคือข้อผิดพลาด p-value และ type I ใช้การปรับเปลี่ยนลำดับการไหลของข้อมูลย้อนหลังซึ่งทำให้สำคัญ "วิธีที่คุณมาที่นี่" และสิ่งที่อาจเกิดขึ้นแทน ในทางตรงกันข้ามกระบวนทัศน์ของ Bayesian เข้ารหัสความสงสัยเกี่ยวกับผลกระทบของพารามิเตอร์เองไม่ใช่จากข้อมูล นั่นทำให้ความน่าจะเป็นหลังแต่ละอันถูกตีความเหมือนกันไม่ว่าคุณจะคำนวณความน่าจะเป็นหลังอื่น ๆ ของเอฟเฟกต์ 5 นาทีที่แล้วหรือไม่ รายละเอียดเพิ่มเติมและการจำลองแบบง่าย ๆ สามารถดูได้ที่http://www.fharrell.com/2017/10/continuous-learning-from-data-no
ดูเหมือนว่าปัญหานี้จะได้รับการแก้ไขโดยP. Armitage, CK McPherson และ BC Rowe (1969), วารสารสมาคมสถิติแห่ง Royal ซีรีส์ (132), 2, 235-244: "การทดสอบความสำคัญอีกครั้งในการสะสมข้อมูล"
มุมมองแบบเบย์เกี่ยวกับปัญหานี้ซึ่งได้กล่าวถึงในที่นี้ก็คือการหารือในBerger and Wolpert (1988), "หลักการความน่าจะเป็น" , มาตรา 4.2
ขนาดเป็นฟังก์ชันของการเพิ่มค่าวิกฤตสำหรับแตกต่างกัน
reps <- 50000
K <- c(1:5, seq(10,50,5), seq(60,100,10)) # the number of attempts a researcher gives herself
alpha <- 0.05
cv <- qnorm(1-alpha/2)
grid.scale.cv <- cv*seq(1,1.5,by=.01) # scaled critical values over which we check rejection rates
max.g <- length(grid.scale.cv)
results <- matrix(NA, nrow = length(K), ncol=max.g)
for (kk in 1:length(K)){
g <- 1
dev <- 0
K.act <- K[kk]
while (dev > -0.01 & g <= max.g){
rej <- rep(NA,reps)
for (i in 1:reps){
k <- 1
accept <- 1
x <- rnorm(K.act)
while(k <= K.act & accept==1){
# each of our test statistics for "samples" of size n are N(0,1) under H0, so just scaling their sum by sqrt(k) gives another N(0,1) test statistic
rej[i] <- abs(1/sqrt(k)*sum(x[1:k])) > grid.scale.cv[g]
accept <- accept - rej[i]
k <- k+1
}
}
rej.rate <- mean(rej)
dev <- rej.rate-alpha
results[kk,g] <- rej.rate
g <- g+1
}
}
plot(K,results[,1], type="l")
matplot(grid.scale.cv,t(results), type="l")
abline(h=0.05)
cv.a <- data.frame(K,adjusted.cv=grid.scale.cv[apply(abs(results-alpha),1,which.min)])
plot(K,cv.a$adjusted.cv, type="l")