scipy.minimize调用自定义函数提示缺失3个位置参数如何解决?
错误原因
scipy.optimize.minimize 对传入的目标函数有固定的参数约定:迭代过程中的待优化参数会作为第一个参数传入目标函数,且传入格式是一维数组。你当前定义的approximate把待优化的a、b、c、d拆成了4个独立的入参,和接口要求不匹配,同时args传入的参数顺序也和函数定义的剩余参数对不上,才会触发参数缺失的报错。
正确实现
两种常用的修改方案,按需选择即可:
方案1:调整目标函数参数结构(推荐)
统一按scipy的接口规范调整误差函数的入参顺序,可读性和可维护性更高:
import numpy as np from scipy.optimize import minimize def rational(a, b, c, d, x): return (a * x + b) / (x ** 2 + c * x + d) # 第一个参数接收待优化的参数数组,内部再拆包 def approximate(params, x, y, func): a, b, c, d = params return np.sum((func(a, b, c, d, x) - y) ** 2) # 调用时参数顺序完全匹配,无报错 res = minimize(approximate, x0=(0, 0, 0, 0), args=(X, Y, rational,), method='Nelder-Mead')
方案2:用匿名函数做参数适配(无需修改原函数)
如果不想改动原有approximate的函数定义,可以在调用时用lambda做一层参数转换:
# 原有函数定义保持不变 def approximate(a, b, c, d, x, y, func): return np.sum((func(a, b, c, d, x) - y) ** 2) # 用lambda把参数数组拆成多个独立参数传入原函数 res = minimize(lambda params, x, y, func: approximate(*params, x, y, func), x0=(0, 0, 0, 0), args=(X, Y, rational,), method='Nelder-Mead')
同类需求最佳实践
- 所有传入scipy优化器的目标函数,都统一将待优化参数放在第一个入参位,用一维数组接收,内部再拆分为对应变量,完全适配官方接口规范,避免参数匹配问题
- 拟合用的样本数据、固定计算逻辑等非优化参数,统一通过
args参数传递,不要硬编码到目标函数内部,提高函数复用性 - 有理函数这类涉及除法的拟合场景,建议给分母加极小常数(比如
1e-12)避免迭代过程中出现除0的数值错误,比如rational函数可以修改为:def rational(a, b, c, d, x): return (a * x + b) / (x ** 2 + c * x + d + 1e-12) - 如果拟合效果不佳,可以尝试更换更适合连续优化的算法(比如L-BFGS-B),有参数范围约束的话直接通过
minimize的bounds参数传入即可。
内容的提问来源于stack exchange,提问作者AAYamoldin
相关产品推荐
相关产品推荐

