使用scipy.minimize做函数极小化时出现RuntimeWarning的原因是什么?
问题原因分析
- 无约束优化的搜索步长会进入不可行域
你使用的Newton-CG是无约束优化算法,不会主动遵守你隐式要求的func(a, x[i])>0约束。虽然初始值a=-1时所有func值均为正,但算法在第一步试搜索步长时,会沿着目标函数下降的方向调整a值:你当前的目标是极小化log_like,算法会尝试让log_like尽可能小,也就是让func的乘积尽可能小。当a被调整到小于≈-2.564时,对应x=0.89的func值1 + 0.39*a会变为负数,触发np.log的无效值警告,导致后续计算出现NaN,优化直接中断,所以你会看到迭代次数nit=0,直接返回初始点的计算结果。 - 目标函数方向不符合常规似然优化逻辑
通常对数似然函数是需要极大化的,如果你直接把log_like传给minimize做极小化,等价于你要让似然值尽可能小,完全背离了参数估计的目标,这也是导致算法往错误方向搜索的核心原因。 Newton-CG不支持边界约束
即使你明确知道a的可行范围,Newton-CG算法本身也不支持传入变量边界约束,自然无法避免搜索到不可行区域。
修复方案
- 调整目标函数:如果是做极大似然估计,将目标改为极小化负对数似然,符合
minimize的优化逻辑 - 计算a的可行边界:根据x的取值,推导得到a的合法范围为
(-1/0.39, 1/0.47),约为(-2.564, 2.128) - 更换支持边界约束的优化算法,比如
L-BFGS-B、TNC或trust-constr
修正后代码示例
import numpy as np from scipy.optimize import minimize def func(a, x): return 1 + (x - 0.5) * a # 改为负对数似然,用于极小化 def neg_log_like(a, x): sum1 = 0 for i in range(len(x)): sum1 += np.log(func(a, x[i])) return -sum1 def neg_log_like_prime(a, x): sum1 = 0 for i in range(len(x)): sum1 += (x[i] - 0.5) / (1 + (x[i] - 0.5) * a) return -sum1 x = [0.89, 0.03, 0.50, 0.36, 0.49] a = -1 # 指定a的可行边界 bounds = [(-1/(0.89-0.5), 1/(0.5-0.03))] a_opt = minimize( neg_log_like, a, args=(x,), method="L-BFGS-B", jac=neg_log_like_prime, bounds=bounds ) print(a_opt)
内容的提问来源于stack exchange,提问作者gautam bhuyan
相关产品推荐
相关产品推荐

