在n> 1000的情况下计算Beta二项式似然

时间:2016-03-24 19:26:52

标签: python numpy scipy statistics sympy

在计算β二项式似然时,我正在努力解决数值精度问题。我的目标是估计某个数字d的概率y mod 10 = d,假设y是二项式(n,p),p是β(a,b)。我正在尝试为大n提出快速解决方案,我的意思是至少1000.似乎给我合理答案的一件事是使用模拟。

def npliketest_exact(n,digit,a,b):
    #draw 1000 values of p 
    probs = np.array(beta.rvs(a,b,size=1000))
    #create an array of numbers whose last digit is digit 
    digits = np.arange(digit,n+1,10)
    #create a function that calculates the pmf at x given p
    exact_func = lambda x,p: binom(n,p).pmf(x)
    #given p, the likeklihood of last digit "digit" is the sum over all entries in digits
    likelihood = lambda p: exact_func(digits,p).sum()
    #return the average of that likelihood over all the draws
    return np.vectorize(likelihood)(probs).mean()

np.random.seed(1)
print npliketest_exact(1000,9,1,1) #0.0992310195195

这可能没问题,但我担心这个策略的精确性。特别是如果有更好/更精确的方法来进行这种计算,我很想知道如何去做。

我已经开始尝试使用对数可能性来得出答案,但即便如此,我也遇到了数值稳定性问题。

def llike(n,k,a,b):
    out = gammaln(n+1) + gammaln(k+a) + gammaln(n-k+b) + gammaln(a+b) - \
            ( gammaln(k+1) + gammaln(n-k+1) + gammaln(a) + gammaln(b) + gammaln(n+a+b) )
    return out

 print exp(llike(1000,9,1,1)) #.000999000999001
 print exp(llike(1000,500,1,1)) #.000999000999001

由于β1,1的平均值为0.5,因此从n = 1000的β二项式获得y = 500的概率应远高于得到9,但上述计算显示可疑的常数值。

我尝试过的另一件事就是使用stackoverflow来处理这个问题的另一件事,就是使用一些聪明的技巧来支持数值稳定性,这显然隐藏在scipy的betaln公式中。

def binomln(n, k): #log of the binomial coefficient 
    # Assumes binom(n, k) >= 0
    return -betaln(1 + n - k, 1 + k) - log(n + 1)

def log_betabinom_exact(n,k,a,b):
    return binomln(n,k) + betaln(k+a,n-k+b) - betaln(a,b)

print exp(log_betabinom_exact(1000,9,1,1)) #.000999000999001
print exp(log_betabinom_exact(1000,500,1,1)) #0.000999000999001

同样,同样可疑的常数。非常感谢任何建议。使用sympy会对此有任何帮助吗?

****跟进

对不起,伙计们,我的哑巴错误,Beta(1,1)是统一的,所以我得到的结果是有道理的。尝试不同的参数会使不同的k值看起来不同。

0 个答案:

没有答案