scipy.optimize.leastsq残差函数移至外部RF模块调用报错如何解决
报错原因
- 第一个
NameError: name 'func' is not defined:RF模块和主代码的作用域相互独立,你在主代码中定义的func = RF.roots属于主模块变量,RF模块的residuals函数无法访问该变量,因此触发未定义错误。 - 后续的参数缺失报错:
scipy.optimize.leastsq要求传入的残差函数第一个参数必须是待优化的参数数组,后续入参按顺序匹配你传入的args元组内的元素。你修改残差函数参数顺序后,要么不符合leastsq的第一个参数要求,要么args内没有传入对应的func参数,导致参数数量不匹配。
可行的实现方案
你完全可以把残差函数迁移到RF文件中,提供两种常用实现方式:
方案1:最简适配(适合固定用RF.roots作为拟合函数的场景)
直接修改RF.py中的residuals函数,调用模块自身的roots方法即可,不需要额外传参:
RF.py修改后代码:
def roots(params, x): a, b, c, d = params y = a * (b * x) ** c + d return y def residuals(params, x, y): # 直接调用同模块下的roots函数即可 return y - roots(params, x)
主代码只要注释掉自己定义的residuals,打开residuals = RF.residuals这一行即可正常运行,其余代码不需要任何修改。
方案2:通用适配(支持传入任意拟合函数计算残差)
如果希望RF模块的残差函数支持适配不同的拟合函数,可以用闭包生成符合leastsq参数要求的残差函数:
RF.py修改后代码:
def roots(params, x): a, b, c, d = params y = a * (b * x) ** c + d return y # 新增残差函数生成器 def generate_residuals(func): def residuals(params, x, y): return y - func(params, x) return residuals
主代码对应修改为:
import numpy as np from scipy.optimize import leastsq import RF func = RF.roots # 传入拟合函数生成符合要求的残差函数 residuals = RF.generate_residuals(func) def estimation(x, y): p_guess = [1, 2, 0.5, 0] params, cov, infodict, mesg, ier = leastsq(residuals, p_guess, args=(x, y), full_output=True) return params # 其余代码保持不变 x = np.array([2.78e-03, 3.09e-03, 3.25e-03, 3.38e-03, 3.74e-03, 4.42e-03, 4.45e-03, 4.75e-03, 8.05e-03, 1.03e-02, 1.30e-02]) y = np.array([2.16e+02, 2.50e+02, 3.60e+02, 4.48e+02, 5.60e+02, 8.64e+02, 9.00e+02, 1.00e+03, 2.00e+03, 3.00e+03, 4.00e+03]) FIT_params = estimation(x, y) print(FIT_params)
内容的提问来源于stack exchange,提问作者Ali_Sh
相关产品推荐
相关产品推荐

