我确实想知道为什么收集数据直到获得显着结果(例如)(即p-hacking)会增加I型错误率?
我也非常感谢R
对此现象的演示。
我确实想知道为什么收集数据直到获得显着结果(例如)(即p-hacking)会增加I型错误率?
我也非常感谢R
对此现象的演示。
Answers:
问题是您给自己太多通过测试的机会。这只是此对话框的精美版本:
我将翻转您,看看谁为晚餐付费。
好吧,我叫团长。
老鼠,你赢了。最好的三分之二?
为了更好地理解这一点,请考虑此顺序过程的简化但现实的模型。假设您将从一定数量的观察值的“试运行”开始,但愿意继续进行更长的实验,以使p值小于。零假设是每个观察值(独立)来自标准正态分布。另一种选择是,独立于均值非零的单位方差正态分布。测试统计量将是所有观测值的平均值除以其标准误差。对于双面测试,临界值为X 我X 我 Ñ ˉ X 1 / √ 0.0250.975Žα=±1.96标准正态分布的和个百分点,大约。
这是一个很好的测试 -对于具有固定样本大小的单个实验。无论是多少,它都有机会拒绝原假设。5 %n
让我们代数基础上,将其转换为等效的测试和所有的值,小号Ñ = X 1 + X 2 + ⋯ + X Ñ = Ñ ˉ X。
因此,当
那是,
如果我们很聪明,那么当变得非常大并且数据仍未进入关键区域时,我们将减少损失并放弃。
这描述了随机游走 。公式等于在随机游动的图周围竖起弯曲的抛物线“栅栏”或障碍:如果随机游动的任何点撞到栅栏,结果都是“显着的” 。(1 )(n ,S n)
如果我们等待足够长的时间,这是随机游走的一个特性,很有可能在某个时候结果看起来很明显。
这里有20个独立的模拟,最多可以有样本。他们都开始在样本上进行测试,这时我们检查每个点是否位于根据公式绘制的障碍之外。从统计测试首次“有意义”的那一点开始,模拟数据被涂成红色。n = 30 (1 )
您可以看到发生了什么:随着增加,随机游走越来越多。障碍物以大约相同的速度散开-但始终不够快以避免随机游走。
在20%的模拟中,发现“显着”差异(通常是在很早的时候),尽管在每个模拟中,零假设都是绝对正确的!运行更多这种类型的模拟,表明真实的测试量接近而不是预期的:也就是说,您愿意继续寻找“显着性”,直到样本量为即使null为true,也会有机会拒绝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值。但这不是真的。在原假设下,p值均匀地分布在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值和I型错误使用了倒退时间倒退信息流调节,这使得“如何到达这里”以及可能发生的事情变得很重要。另一方面,贝叶斯范式编码的怀疑论是对参数本身而不是数据的影响。不管您是否在5分钟前计算了效果的另一个后验概率,每个后验概率的解释都是相同的。可以在http://www.fharrell.com/2017/10/continuous-learning-from-data-no上找到更多详细信息和简单的模拟。
P. Armitage,CK McPherson和BC Rowe(1969),《皇家统计学会杂志》似乎已经解决了这个问题。系列A(132),2,235-244:“有关累积数据的重复意义测试”。
顺便提一下,贝叶斯对此问题的观点也在Berger和Wolpert(1988)的“似然原理”第4.2节中进行了讨论。
大小随不同临界值增加的函数
调整了临界值以恢复5%的测试值(的函数)
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")