Python执行极小化运算时出现除零错误:高斯对数似然scipy优化失败
问题原因分析
- 初始点距离分布均值过远导致数值下溢:你使用的高斯分布标准差约为0.0115,初始迭代点1和均值1.54379的差值接近47倍标准差,该位置的概率密度已经低于浮点数最小可表示阈值,被截断为0,
np.log(0)直接触发divide by zero警告,返回的负无穷取负后为正无穷,优化器无法基于无穷大的损失值进行迭代,最终触发迭代次数上限报错,第二条减法警告也是因为所有点的损失都是无穷大,无法计算差值导致的。 - 数值计算逻辑不合理:直接对
pdf的输出取对数会放大下溢问题,scipy的所有分布类都原生提供logpdf方法,直接在对数域计算概率,完全可以避免下溢问题。另外一维场景使用multivariate_normal属于不必要的复杂操作,容易出现参数传递错误。
修复方案
方案1:使用单变量正态分布+logpdf(推荐)
该方案性能更高,参数逻辑更清晰,不需要调整初始点即可正常运行:
import numpy as np from scipy.stats import norm from scipy.optimize import minimize as scipy_min def f_loglike(x): pmean = 1.54379044 pstd = np.sqrt(0.00013136) # 直接调用logpdf避免数值下溢 return -norm(loc=pmean, scale=pstd).logpdf(x) # 运行优化 res = scipy_min(f_loglike, 1, method='Nelder-Mead', tol=1e-6) print(res)
运行后输出的x字段会和pmean完全一致,优化成功。
方案2:保留multivariate_normal的修正版
如果你必须使用多元正态分布的实现,只要替换为logpdf调用即可:
import numpy as np from scipy.stats import multivariate_normal from scipy.optimize import minimize as scipy_min def f_loglike(x): pmean = [1.54379044] pCov = [[0.00013136]] return -multivariate_normal(pmean, pCov).logpdf(x) scipy_min(f_loglike, 1, method='Nelder-Mead', tol=1e-6)
调试技巧
后续遇到类似对数计算报错时,可以先打印损失函数的中间输出值,比如本例中先打印pdf(x)的结果,很快就能发现初始点的返回值为0,直接定位下溢问题。
内容的提问来源于stack exchange,提问作者JohnDoe122
相关产品推荐
相关产品推荐

