lmfit自定义模型拟合时无法固定参数,求正确设置方法
lmfit固定参数不生效、参数超出约束的问题解决
问题背景
自定义lmfit模型拟合数据集时,遇到两个异常:
- 设置
params['C'].vary = False后,参数C仍被优化 - 给RS设置了
min=0的约束,拟合结果中RS却为负数
原代码
import numpy as np from lmfit import Model data = np.loadtxt('impedance.txt') w = data[:, 0] y1 = data[:, 1] y2 = data[:, 2] z = y1/y2 f = w/(2.*np.pi) def Ztot(f, RP=1E4, RS=10, C=1E-9, L=10E-3): return np.abs((1/((1/RP + 1/(complex(0, 1)*2*np.pi*f*L))**(-1) + RS) + complex(0, 1)*2*np.pi*f*C)**(-1)) gmodel = Model(Ztot) params = gmodel.make_params() params['RS'].max = 100 params['RS'].min = 0 params['C'].vary = False print(params) result = gmodel.fit(z, f=f) print(result.fit_report())
异常拟合结果
[[Variables]] RP: 75381.4485 (init = 10000) RS: -2280.34148 (init = 10) C: 3.6066e-10 (init = 1e-09) L: 0.06200475 (init = 0.01)
问题原因及解决办法
1. 固定参数不生效:未传入自定义参数配置
你已经创建并修改了params对象,但调用fit()时没有将这个配置好的参数对象传进去。默认情况下,fit()会重新生成一套默认参数,完全覆盖你之前的修改。
解决: 在fit()中显式传入params参数
result = gmodel.fit(z, params=params, f=f)
2. 参数超出约束:优化器选择或模型特性导致
lmfit默认使用的leastsq优化器(基于scipy的leastsq)对边界约束的支持有限,再加上你的模型返回复数的绝对值,可能让残差函数出现平坦区域,导致优化器无视边界。
解决: 切换到支持边界约束的优化器,比如lbfgsb或nelder
result = gmodel.fit(z, params=params, f=f, method='lbfgsb')
修改后的完整代码
import numpy as np from lmfit import Model data = np.loadtxt('impedance.txt') w = data[:, 0] y1 = data[:, 1] y2 = data[:, 2] z = y1/y2 f = w/(2.*np.pi) def Ztot(f, RP=1E4, RS=10, C=1E-9, L=10E-3): return np.abs((1/((1/RP + 1/(complex(0, 1)*2*np.pi*f*L))**(-1) + RS) + complex(0, 1)*2*np.pi*f*C)**(-1)) gmodel = Model(Ztot) params = gmodel.make_params() params['RS'].max = 100 params['RS'].min = 0 params['C'].vary = False # 传入配置好的参数,并使用支持边界的优化器 result = gmodel.fit(z, params=params, f=f, method='lbfgsb') print(result.fit_report())
内容的提问来源于stack exchange,提问作者Nikolaij
相关产品推荐
相关产品推荐

