Scipy.Minimize调用报错:缺少参数b,如何复现R的Beta-二项式MLE?
Python中Beta-二项式负对数似然优化的参数传递问题
问题原因分析
你遇到的TypeError是Scipy minimize函数的参数传递规则导致的——它会把你传入的x0作为单一的数组/向量参数传给目标函数,而不是自动拆分成a和b两个独立参数。你的nll(a, b)函数定义成了接收两个位置参数,所以当minimize把[1,10]作为一个数组传进去时,函数只收到了第一个参数(这个数组),自然会报缺少b的错误。
另外,你的负对数似然计算还有个潜在问题:通常我们直接用负的对数似然值做最小化,而不是取负的指数化对数似然(-(np.exp(log))),后者会损失数值稳定性,也不符合常规的负对数似然定义。
修正方案
1. 调整目标函数的参数格式
把nll改成接收单个数组参数,再从中拆分出a和b:
def nll(params): # 从传入的数组中拆分出alpha和beta参数 a, b = params k = players['Goals'].sum() # 成功次数 n = players['Shots'].sum() # 试验次数 # 计算对数似然 log_likelihood = 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 -log_likelihood
2. 完善minimize调用(添加参数边界)
对应R代码中的lower参数,L-BFGS-B方法需要通过bounds指定参数的有效范围,避免参数取到非正值(Beta分布的参数必须>0):
from scipy.optimize import minimize from scipy.special import gammaln import numpy as np init_params = [1, 10] # 对应R中的start参数 # 设置参数边界:alpha >=0.0001,beta >=0.1 bounds = [(0.0001, None), (0.1, None)] res = minimize(nll, x0=init_params, method='L-BFGS-B', bounds=bounds, options={'disp' : True, 'maxiter': 250}) # 查看估计结果 print("估计的alpha和beta参数:", res.x)
关键说明
- Scipy的
minimize所有优化目标函数都要求参数是一个一维数组,不管你有多少个待估参数,都需要在函数内部自行拆分。 - 去掉指数化步骤后,我们直接最小化负对数似然,这和最大化似然是完全等价的,但数值计算更稳定(避免指数化带来的溢出或下溢问题)。
bounds参数是L-BFGS-B方法的必需项(如果要限制参数范围),和R代码里的lower参数作用完全一致。
内容的提问来源于stack exchange,提问作者HJA24
相关产品推荐
相关产品推荐

