Scipy fmin参数传递问题排查及学生方案差异解析
关于scipy.optimize.fmin参数传递与对数似然函数的问题解答
1. 你的代码无法正常运行的原因
你的代码存在三处核心错误:
- 目标函数返回值错误:你的
LogL函数返回的是长度与data一致的数组(因normalpdf处理数组输入后输出数组,np.log保留了数组结构),但fmin要求目标函数必须返回单个标量值,这直接导致后续优化逻辑报错。同时你定义的Logln=0累加逻辑完全无效,没有实现对数似然的求和需求。 - 初始值设置错误:你要估计的是两个参数(均值
mu和标准差sigma),但初始值x0=1是单个数值,与待优化参数数量不匹配,fmin无法基于此迭代更新参数向量。 - 参数传递逻辑混乱:
- 你将函数
vect_q直接赋值给q而非调用函数(正确应为q=vect_q()),导致q[0]触发“函数不可下标”的错误。 - 错误使用
args参数:fmin的args用于传递固定不变的额外参数,而你的LogL仅接收待优化的参数向量,不需要额外固定参数,因此所有带args的调用都是冗余且错误的。
- 你将函数
错误示例代码:
# 返回数组而非标量,不符合fmin要求 def LogL(q): return Logln + (- np.log(normalpdf(data,q[0],q[1])))
2. 同学的LogL函数为何返回数值而非函数
同学的LogL函数通过np.sum()将样本的对数概率密度数组求和,转换为单个标量值:
def LogL(q): return -np.sum(np.log(normalpdf(data, q[0],q[1])))
根据最大似然估计的定义,对数似然是所有样本对数概率的总和,必须转换为标量才能让优化算法判断“当前参数的优劣”——fmin需要一个数值来衡量参数对应的目标函数值,进而迭代寻找最小值。
3. 同学的方案能成功求得最小值的原因
同学的代码完全契合fmin的运行逻辑:
- 目标函数符合要求:
LogL(q)接收长度为2的参数向量q(q[0]对应mu,q[1]对应sigma),返回单个标量形式的负对数似然值。最大化似然等价于最小化负对数似然,目标函数定义正确。 - 初始值匹配参数数量:初始值
[MU, SIGMA]是长度为2的列表,与待优化的参数数量一致,为fmin提供了合理的迭代起点。 - 参数传递逻辑正确:
fmin会自动将初始参数向量传入LogL,迭代更新向量中的值,直到找到使目标函数最小的参数组合,无需额外传递args参数,所有待优化参数已包含在q中。
可行代码示例
import numpy as np from scipy.optimize import fmin MU = 1.3 SIGMA = 4.5 N = 1000 data = np.random.normal(MU, SIGMA, N) def normalpdf(x,mu,sigma): return ((1/(sigma*np.sqrt(2*np.pi)))*(np.exp(-(((x-mu)**2))/(2*sigma**2)))) def LogL(q): return -np.sum(np.log(normalpdf(data, q[0], q[1]))) # 调用fmin,初始值为真实参数的初始猜测 minimum = fmin(LogL, [MU, SIGMA]) print("估计的参数:", minimum)
内容的提问来源于stack exchange,提问作者Sarawara
相关产品推荐
相关产品推荐

