Python 用scipy.optimize和对数似然法求β二项分布的α和β

Python 用scipy.optimize和对数似然法求β二项分布的α和β,python,scipy,distribution,beta,binomial-theorem,Python,Scipy,Distribution,Beta,Binomial Theorem,如果二项分布中的成功概率p具有形状参数α>0和β>0的β分布,则该分布为β二项分布。形状参数定义了成功的概率。 我想从贝塔二项分布的角度找出最能描述我的数据的α和β值。我的数据集players包含许多棒球运动员的击球次数(H)、击球次数(AB)和转换(H/AB)数据。我在JulienD的回答的帮助下估算PDF 接下来,我写一个我们将最小化的对数似然函数 def loglike_betabinom(params, *args): """ Negative log likelihood

如果二项分布中的成功概率p具有形状参数α>0和β>0的β分布,则该分布为β二项分布。形状参数定义了成功的概率。 我想从贝塔二项分布的角度找出最能描述我的数据的α和β值。我的数据集
players
包含许多棒球运动员的击球次数(H)、击球次数(AB)和转换(H/AB)数据。我在JulienD的回答的帮助下估算PDF

接下来,我写一个我们将最小化的对数似然函数

def loglike_betabinom(params, *args):
   """
   Negative log likelihood function for betabinomial distribution
   :param params: list for parameters to be fitted.
   :param args:  2-element array containing the sample data.
   :return: negative log-likelihood to be minimized.
   """

   a, b = params[0], params[1]
   k = args[0] # the conversion rate
   n = args[1] # the number of at-bats (AE)

   pdf = comb(n, k) * beta(k + a, n - k + b) / beta(a, b)

   return -1 * np.log(pdf).sum()   
现在,我想写一个函数,最小化loglike_betabinom

结果为[-6.04544138 2.03984464],这意味着α为负,这是不可能的。我的脚本基于以下R代码段。他们得到[101.359287.318]

 ll <- function(alpha, beta) { 
    x <- career_filtered$H
    total <- career_filtered$AB
    -sum(VGAM::dbetabinom.ab(x, total, alpha, beta, log=True))
 }

 m <- mle(ll, start = list(alpha = 1, beta = 10), 
 method = "L-BFGS-B", lower = c(0.0001, 0.1))

 ab <- coef(m)

ll需要注意的一点是,对于数据集中的
n
k
值,对数似然中的
comb(n,k)
可能在数值上表现不好。您可以通过对数据应用
comb
来验证这一点,并查看是否出现
inf
s

修正的一种方法是重写中建议的负对数似然,即作为伽马函数对数的函数,如中所示

from scipy.special import gammaln
import numpy as np

def loglike_betabinom(params, *args):

    a, b = params[0], params[1]
    k = args[0] # the OVERALL conversions
    n = args[1] # the number of at-bats (AE)

    logpdf = 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 -np.sum(logpdf) 
然后,您可以使用

from scipy.optimize import minimize

init_params = [1, 10]
# note that I am putting 'H' in the args
res = minimize(loglike_betabinom, x0=init_params,
            args=(players['H'], players['AB']),
            method='L-BFGS-B', options={'disp': True, 'maxiter': 250})
print(res)
这应该会产生合理的结果


如果您想进一步返工代码,您可以查看灵感。

现在如何最小化损失函数?您是否编写了自己的方法,或者使用了某个包中的内容?无论哪种方式,详细信息是什么?我使用scipy.optimize import minimize
@HJA24什么是
玩家
?你能分享这些数据吗?这是我测试我的答案所缺少的部分。你在哪里指定你要传递给
minimize
bounds
?我删除了bounds部分
from scipy.special import gammaln
import numpy as np

def loglike_betabinom(params, *args):

    a, b = params[0], params[1]
    k = args[0] # the OVERALL conversions
    n = args[1] # the number of at-bats (AE)

    logpdf = 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 -np.sum(logpdf) 
from scipy.optimize import minimize

init_params = [1, 10]
# note that I am putting 'H' in the args
res = minimize(loglike_betabinom, x0=init_params,
            args=(players['H'], players['AB']),
            method='L-BFGS-B', options={'disp': True, 'maxiter': 250})
print(res)