如果二项式分布具有形状参数α> 0 和β的beta分布,则成功的概率为 p ,则该分布为beta-二项式。 > 0 。形状参数定义成功的可能性。
我想找到α和β的值,它们从β二项分布的角度最能描述我的数据。我的数据集players
由命中数( H ),击球数( AB )和转换数( H / AB )。我借助Beta Binomial Function in Python
from scipy.special import beta
from scipy.misc import comb
pdf = comb(n, k) * beta(k + a, n - k + b) / beta(a, b)
接下来,我编写一个将最小化的对数似然函数。
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
最小化的函数 from scipy.optimize import minimize
init_params = [1, 10]
res = minimize(loglike_betabinom, x0=init_params,
args=(players['H'] / players['AB'], players['AB']),
bounds=bounds,
method='L-BFGS-B',
options={'disp': True, 'maxiter': 250})
print(res.x)
结果为[-6.04544138 2.03984464],这意味着α为负,这是不可能的。我的脚本基于以下R代码段。他们得到[101.359,287.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)
有人可以告诉我我做错了吗?非常感谢帮助!
答案 0 :(得分:5)
要注意的一件事是,对于数据集中comb(n, k)
和n
的值,对数似然中的k
可能在数值上表现不佳。您可以通过对数据应用comb
来验证这一点,并查看是否出现inf
个。
一种修改方法的方法可以是重写https://stackoverflow.com/a/32355701/4240413中建议的负对数似然性,即,根据Gamma函数对数的函数来重写
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)
这应该会给出合理的结果。
如果您想进一步修改代码,可以查看How to properly fit a beta distribution in python?的灵感。