如何找到事件总数的置信区间


9

我有检测器,它将以概率p检测事件。如果检测器说发生了事件,则情况总是如此,因此不会出现假阳性。运行一段时间后,我检测到k个事件。我想以一定的可信度(例如95%)计算发生,检测到或以其他方式发生的事件总数。

举例来说,假设我检测到13个事件。我希望能够基于p计算出13到19个事件,置信度为95%。

到目前为止,这是我尝试过的方法:

如果总共有n个事件,则检测到k个事件的概率为:

binomial(n, k) * p^k * (1 - p)^(n - k)

k到无穷大的n的总和为:

1/p

这意味着总共有n个事件的概率为:

f(n) = binomial(n, k) * p^(k + 1) * (1 - p)^(n - k)

因此,如果我想确保95%的比例,我应该找到f(k) + f(k+1) + f(k+2) ... + f(k+m)至少为0.95 的第一部分和,答案为[k, k+m]。这是正确的方法吗?还有答案的封闭公式吗?

Answers:


11

我会选择使用负二项式分布,当成功的恒定概率为p时,它返回在第k_th个成功之前将有X个失败的概率。

使用一个例子

k=17 # number of successes
p=.6 # constant probability of success

失败的平均值和标准差由下式给出

mean.X <- k*(1-p)/p
sd.X <- sqrt(k*(1-p)/p^2) 

失效X的分布将具有近似的形状

plot(dnbinom(0:(mean.X + 3 * sd.X),k,p),type='l')

因此,失败的次数大约为(95%置信度)

qnbinom(.025,k,p)
[1] 4

qnbinom(.975,k,p)
[1] 21

因此,您的整数将为[k + qnbinom(.025,k,p),k + qnbinom(.975,k,p)](使用示例数字[21,38])


5

假设您要选择n,p(n)的分布,则可以应用贝叶斯定律。

您知道给定n实际发生的k个事件发生的概率是由二项分布决定的

p(k|n)=(nk)pk(1p)(nk)

假设您观察到k,那么您真正想知道的是实际发生n个事件的概率。由贝叶斯奠定:

p(n|k)=p(k|n)p(n)p(k)

通过应用总概率定理,我们可以写:

p(n|k)=p(k|n)p(n)np(k|n)p(n)

因此,如果没有进一步的信息,关于的分布就无法进行进一步的研究。p(n)

然而,如果要挑选一个分布针对其存在的值大于其中,或非常接近零,那么你可以做一个好一点。例如,假设的分布在范围内是均匀的。这个案例:p(n)np(n)=0n[0,nmax]

p(n)=1nmax

贝叶斯公式简化为:

p(n|k)=p(k|n)np(k|n)

至于问题的最后一部分,我同意最好的方法是对进行累积求和,以生成累积概率分布函数,然后迭代直到达到0.95的极限。p(n|k)

鉴于此问题是从SO迁移过来的,因此下面附有python中的玩具示例代码

import numpy.random

p = 0.8
nmax = 200

def factorial(n):
    if n == 0:
        return 1
    return reduce( lambda a,b : a*b, xrange(1,n+1), 1 )

def ncr(n,r):
    return factorial(n) / (factorial(r) * factorial(n-r))

def binomProbability(n, k, p):
    p1 = ncr(n,k)
    p2 = p**k
    p3 = (1-p)**(n-k)
    return p1*p2*p3

def posterior( n, k, p ):
    def p_k_given_n( n, k ):
        return binomProbability(n, k, p)
    def p_n( n ):
        return 1./nmax
    def p_k( k ):
        return sum( [ p_n(nd)*p_k_given_n(nd,k) for nd in range(k,nmax) ] )
    return (p_k_given_n(n,k) * p_n(n)) / p_k(k)


observed_k   = 80
p_n_given_k  = [ posterior( n, observed_k, p ) for n in range(0,nmax) ]
cp_n_given_k = numpy.cumsum(p_n_given_k)
for n in xrange(0,nmax):
    print n, p_n_given_k[n], cp_n_given_k[n]

3

如果您测量了事件并且知道检测效率为,则可以自动将测量结果校正为“真实”计数。kpktrue=k/p

然后,您的问题是要找到的范围,其中95%的观测值将落入该范围。您可以使用Feldman-Cousins方法估计此间隔。如果您有权访问ROOT,则有一个类可以为您执行此计算。ktrue

您可以使用Feldman-Cousins从未校正的事件计算上限和下限 ,然后使用它们放大到100%。这样,实际的测量次数将确定您的不确定性,而不是某些未测量的定标数字。k1/p

{
gSystem->Load("libPhysics");

const double lvl = 0.95;
TFeldmanCousins f(lvl);

const double p = 0.95;
const double k = 13;
const double k_true = k/p;

const double k_bg = 0;

const double upper = f.CalculateUperLimit(k, k_bg) / p;
const double lower = f.GetLowerLimit() / p;

std::cout << "["
  lower <<"..."<<
  k_true <<"..."<<
  upper <<
  "]" << std::endl;
}

谢谢,这看起来很棒。我认为这是我一直在寻找的答案。
Statec

2

我认为您误解了置信区间的目的。置信区间使您可以评估参数的真实值所在的位置。因此,根据您的情况,您可以为构造一个置信区间。为数据构造时间间隔没有任何意义。p

话虽如此,一旦有了的估计值,就可以使用二项式pdf计算出观察到不同实现(例如14、15等)的概率。p


好吧,我已经知道了。我也知道检测到的事件数量:k。因此,总事件数约为k / p。我想找出k / p左右的间隔,因此可以说95%的事件总数在其中。这更有意义吗?
Statec 2010年

我相信OP正在尝试计算二项式采样中N的间隔,其中p是已知的。尝试这样做很有意义。
Glen_b-恢复莫妮卡(Monica)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.