为什么 ANOVA 不是 p-hacking?

机器算法验证 方差分析 黑客攻击
2022-03-21 06:39:00

假设我们有一些带有许多参数的数据。举个例子,假设我是一个为食品网站工作的不那么道德的记者,我正在寻找一些“有科学支持”的点击诱饵文章,讲述一些食物或生活方式对你的好处/坏处。

我的数据可能包含数千人的集合,他们的社会经济地位,早餐吃什么,是否素食,喜欢茶还是咖啡等,以及他们的智商测试分数。

如果我将数据集分成许多(100+)组,其中第一组可能会划分素食者/肉食者,第二组可能会划分咖啡饮用者和茶饮用者,第三组可能会划分女性咖啡饮用者和男性饮茶者等。如果然后使用 ANOVA比较所有组以查看是否存在统计学上的显着差异,这不是有效的 p-hacking 吗?

我知道 ANOVA 不会告诉我们哪些组不同,但它似乎是一种快速确认其中存在(假)阳性的方法。然后是找出哪些组不同的案例。

3个回答

这不是 p-hacking。比较了多个组,但只测试了一个假设。

ANOVA 计算方差比率,并且可以基于单个假设计算该比率的 p 值。

可能会出现“anova = p-hacking”的想法,因为假设检验通常不用于检验零假设,而是为替代假设提供证明/证明(一次可以有多个) .

请注意,ANOVA 具有以下属性

  • ANOVA 并不能说明许多组中的一个是不同的,而只是它们不一样。
  • 对于所有类型的组组合,方差分析不如单独的 t 检验强大。

如果我将数据集分成许多(100+)组,其中第一组可能会划分素食者/肉食者,第二组可能会划分咖啡饮用者和茶饮用者,第三组可能会划分女性咖啡饮用者和男性饮茶者等。如果然后使用 ANOVA比较所有组以查看是否存在统计学上的显着差异,这不是有效的 p-hacking 吗?

目前尚不清楚您将如何进行这种拆分和方差分析。使用 ANOVA,您可以有多个组,但这些组不应重叠。您可能会使用所有这些变量做一个线性模型之类的事情,但是每个额外的组/变量都会降低自由度并使 ANOVA 测试不那么敏感/强大。

您似乎将p hacking 与涉及多个二进制解释变量的统计方法的应用混淆了(另见下文,我在 ANOVA之后处理事后测试)。这让我想起了“任何人都可以用统计数据撒谎!”的指责。这虽然是真的,但并没有揭示有关统计数据的一些特殊真相:在描述人类交流时,您可以直接假设“任何人都可以撒谎”句号。

无论采用何种统计方法(例如,ANOVA 或其他方法),术语p hacking表示研究人员(或研究小组)优先报告“具有统计意义的发现”而不是报告“具有科学实质性的发现”(无论是正面的还是负面的)……如果不完全放弃对科学实质发现的报告。因此,p hacking 与其说是一种特定的统计方法(ANOVA 或其他),不如说它是一种针对人们对该方法所做的事情(以及研究设计、测量、参与者的选择、推理水平等)的方向。

如果您不确定自己是否是 p hacking,那么一个很好的提示的研究是否由您的特定研究领域中的一个结构良好的理论驱动的问题引导,这个问题的回答是有价值的,(选择研究方法,包括该问题导致的统计方法),或者您是否从特定的统计方法开始并寻找“问题”来回答。

最后,ANOVA(和其他综合假设检验)正如他们在包装上所说的那样:确定对于给定的I 类错误率(即) ,所有组之间的相似性是否存在足够的偏差。当然,p hacking 确实在事后成对测试中发挥了作用——如果有个组,那么其中有个,这提供了一个很好的机会(特别是一个机会)被报告为“统计显着”的误报。p hacking 研究人员可以通过使用多重比较调整策略(例如,αkk2k2α错误发现率全族错误率等)。

Randall Munroe 的“重要”总是值得一笑,而且是密切相关的,所以我在这里再次包括在内。:)

兰德尔·门罗 (Randal Munroe) 的 xkcd 的“重要”

毫无疑问,如您所描述的,如果在许多随机数据集上重复使用,ANOVA(以及任何其他统计测试)都可以用于 P-hacking。

在 5% 的水平上,大约 20 个测试中有 1 个的 P 值低于 0.05。

基于连续检验统计量的精确检验H0

下面显示的是 (a) 具有正态数据的 t.tests、(b) 具有二项式计数的精确二项式检验和 (c) 具有正态数据的单样本 Wilcoxon 检验的模拟。

为真时:只有 t.test 显示 P 值的标准均匀分布。二项式检验的 P 值尽可能接近 5%(不超过 5%),因此不存在正好处于 5% 水平的(非随机)二项式检验。Wilcoxon 检验基于等级;因此检验统计量是不连续的。但是可以进行接近 5% 水平的测试。H0

在此处输入图像描述

图的R代码:

set.seed(1234)
pv.t = replicate(10^5, 
         t.test(rnorm(25, 100, 15), mu = 100)$p.val)
mean(pv.t <= 0.05)
[1] 0.05017       # 5% within margin of sim error


set.seed(1235)
pv.b = replicate(10^5, 
        binom.test(rbinom(1, 10, .5), 10)$p.val)
mean(pv.b <= 0.05)
[1] 0.02173     # No test at exactly 5% available
                #  This test rejects for x=0,1,9, or 10
set.seed(1236)
pv.w = replicate(10^5, 
        wilcox.test(rnorm(25, 100, 15), mu = 100)$p.val)           
mean(pv.w <= 0.05)
[1] 0.04905       # test very nearly at 5%

par(mfrow=c(1,3))
 hist(pv.t, prob=T, col="skyblue2", main="T Test")
  curve(dunif(x), add=T, col="brown", lwd=2)
  abline(v=.05, col="red", lty="dotted", lwd=2)
 hist(pv.b, prob=T, col="skyblue2", main="Exact Binomial Test")
  curve(dunif(x), add=T, col="brown", lwd=2)
  abline(v=.05, col="red", lty="dotted", lwd=2)
 hist(pv.w, prob=T, col="skyblue2", main="Wilcoxon Test")
  curve(dunif(x), add=T, col="brown", lwd=2)
  abline(v=.05, col="red", lty="dotted", lwd=2)
par(mfrow=c(1,1))