未知的 p 值计算

机器算法验证 r 假设检验 p 值
2022-03-05 06:55:50

最近在调试一个R脚本,发现很奇怪,作者自己定义了p值函数

pval <- function(x, y){
    if (x+y<20) { # x + y is small, requires R.basic
        p1<- nChooseK(x+y,x) * 2^-(x+y+1);
        p2<- nChooseK(x+y,y) * 2^-(x+y+1);
        pvalue = max(p1, p2)
    }
    else { # if x+y is large, use approximation
        log_p1 <- (x+y)*log(x+y) - x*log(x) - y*log(y) - (x+y+1)*log(2);
        pvalue<-exp(log_p1);
    }
    return(pvalue)
}

其中 X 和 Y 是大于 0 的正值。<20 的情况似乎是某种超几何分布的计算(类似于 Fisher 检验?),有人知道其他计算是什么吗?作为旁注,我正在尝试优化此代码,以便找出正确的 R 函数来调用和替换它。

编辑:可在此处找到用于 p 值计算的论文详细公式(需要单击 pdf 以查看公式)方法从 pdf 的第 8 页开始,有问题的公式可以在第 9 页的 (1) 下找到。他们假设的分布是泊松分布。

1个回答

第二件事看起来像是用于x+y < 20案例的计算的近似值,但基于斯特林近似值

通常当它被用于这种近似时,人们至少会使用下一个附加项(因子2πn近似于n!),这将大大改善相对近似n.

例如,如果xy都是 10,第一次计算得出大约 0.088,而当因子为2πn包含在所有项中约为 0.089,对于大多数目的来说已经足够接近了……但是在近似值中省略该项会得到 0.5 - 这真的不够接近!该函数的作者显然没有费心检查他在边界情况下的近似值的准确性。

为此,作者可能应该简单地调用内置lgamma函数 - 具体来说,通过使用 this 而不是他所拥有的log_p1

log_p1 <- lgamma(x+y+1)-lgamma(x+1)-lgamma(y+1)-(x+y+1)*log(2)

这导致他试图近似的答案(因为lgamma(x+1)实际上返回log(x!),他试图通过斯特林近似来近似 - 糟糕 - 的东西)。

同样,我不确定作者为什么不使用choose第一部分中的内置函数,这是 R 标准发行版中的一个函数。就此而言,相关的分布函数可能也是内置的。

您实际上并不需要两个单独的案例;一个lgamma工作得很好,直到最小值。另一方面,该choose函数适用于相当大的值(例如choose(1000,500)工作得很好)。更安全选择可能是lgamma,尽管你需要有相当大的xy在它成为一个问题之前。

有了更多信息,应该可以确定测试的来源。我的猜测是作者从某个地方拿走了它,所以应该可以找到它。你对此有一些背景吗?

当你说“优化”时,你的意思是让它更快、更短、更易于维护还是别的什么?


快速阅读论文后编辑:

作者在很多方面似乎是错误的。费舍尔的精确检验不假设边距是固定的,它只是以它们为条件,这根本不是一回事,正如所讨论的那样,例如,here,有参考文献。事实上,他们似乎完全不知道关于利润条件以及为什么这样做的辩论。那里的链接值得一读。

这篇论文的作者至少似乎明白,他们给出的概率必须经过累积才能给出 p 值。例如在第 5 页第一列的中间附近(强调我的):

根据 Fisher 精确检验对此类结果的统计显着性为 4.6%(双尾 P 值,即在肌动蛋白 EST 频率与 cDNA 文库无关的假设中出现此类表的概率)。相比之下,从等式 2 的累积形式 (等式 9,参见方法)计算的 P 值(即,肌动蛋白 EST 的相对频率在两个文库中相同,假设至少有 11 个同源 EST 在脑库中观察到两次后的肝库)为1.6%。

(虽然我不确定我是否同意他们计算那里的价值;我必须仔细检查,看看他们实际上对另一条尾巴做了什么。)

我认为该程序不会那样做。

但是请注意,他们的分析不是标准的二项式检验;他们使用贝叶斯参数在其他常客测试中推导出 p 值。他们似乎也——在我看来有点奇怪——以x, 而不是x+y. 这意味着他们最终必须得到类似负二项式而不是二项式的结果,但我发现这篇论文的组织非常糟糕,解释得也非常糟糕(而且我习惯于弄清楚统计论文中发生了什么),所以我除非我仔细检查,否则无法确定。

我什至不相信他们的概率之和在这一点上是 1。

这里还有很多要说的,但问题不在于论文,而在于程序中的实现。

--

无论如何,结果是,至少论文正确地确定了 p 值由等式 2 中的概率之和组成,但程序没有(参见本文方法部分的 eqn 9a 和 9b。)

代码在这方面是完全错误的。

pbinom[正如@whuber 的评论所暗示的那样,您可以使用来计算单个概率(但不是尾部,因为它不是二项式检验,因为它们构造它)但是在他们的等式 2 中有一个额外的因子 1/2 所以如果你想在论文中复制结果,你需要改变它们。]

你可以通过一些摆弄来获得它pnbinom-

负二项式的通常形式是试验次数kth成功或失败的次数kth成功。两者是等价的;维基百科在这里给出了第二种形式概率函数为:

(k+r1k)(1p)rpk,

p4 上的等式 2(p3 上的等式 1 也是如此)是负二项式,但移动了 1。令p=N1/(N1+N2)k=xr=y+1

的限制没有被类似地改变,它们的概率甚至可能不会增加到 1。y

那会很糟糕。