我正在尝试使用lmfit拟合一些数据。最初,我使用Model类,该类根据此示例/教程运行良好: https://lmfit.github.io/lmfit-py/model.html 但是后来我想向模型添加一些参数约束,因此我看了本教程: https://lmfit.github.io/lmfit-py/parameters.html
但是,在将两个类组合在一起以使它们很好地协同工作时,我遇到了一些问题。 它要么抱怨fit函数缺少参数,要么抱怨参数无效(在我将发布的示例中就是这种情况),或者我得到的模型实际上并没有采用我指定的参数。 我实际上可以使用以下不同方法之一解决问题: 1.使用model.make_params(...)传递参数,但我想将它们单独拆分 2.我可以使用Minimizer代替Model,但是我想了解为什么它们实现如此不同,尽管我希望它们非常相似(除了它们适用于不同类型的输入)
任何帮助/解释将不胜感激。 :)
此代码基于“参数”教程页面上的示例。 我在这里所做的是修改示例,以便使用Model类而不是Minimizer类,该类原则上应该起作用,但是我以某种方式做错了。 作为比较,原始示例在此处(滚动到底部): https://lmfit.github.io/lmfit-py/parameters.html
# <examples/doc_parameters_basic.py>
import numpy as np
from lmfit import Model, Parameters
# create data to be fitted
x = np.linspace(0, 15, 301)
data = (5. * np.sin(2*x - 0.1) * np.exp(-x*x*0.025) +
np.random.normal(size=len(x), scale=0.2))
# define objective function: returns the array to be minimized
def fcn2min(params, x):
"""Model a decaying sine wave and subtract data."""
amp = params['amp']
shift = params['shift']
omega = params['omega']
decay = params['decay']
model = amp * np.sin(x*omega + shift) * np.exp(-x*x*decay)
return model
# create a set of Parameters
params = Parameters()
params.add('amp', value=10, min=0)
params.add('decay', value=0.1)
params.add('shift', value=0.0, min=-np.pi/2., max=np.pi/2)
params.add('omega', value=3.0)
# do fit, here with leastsq model
fitmodel = Model(fcn2min)
result = fitmodel.fit(data, params, x=x)
# calculate final result
final = result.fit_report()
# try to plot results
try:
import matplotlib.pyplot as plt
plt.plot(x, data, 'k+')
plt.plot(x, final, 'r')
plt.show()
except ImportError:
pass
# <end of examples/doc_parameters_basic.py>
但是像这样使用它,我得到一个错误
ValueError: Invalid independent variable name ('params') for function fcn2min
我尝试过: 将所有参数都指定为函数参数,例如
def fcn2min(x, amp, shift, omega, decay):
但是在这种情况下,我最终没有连接模型/功能参数,却得到了一个“不适合”的东西。
现在我尝试指定以下内容:
fitmodel = Model(fcn2min, independent_vars=['x'], param_names=params)
但是在这种情况下,我得到了
Invalid parameter name ('amp') for function fcn2min
也尝试过这样的事情:
params = fitmodel.make_params()
params.add('amp', value=10, min=0)
...
但是在这种情况下,我也没有获得与模型连接的参数,可以从
的输出中看到fitmodel.param_names
返回一个空列表。
答案 0 :(得分:0)
您混淆了Model
类包装的模型函数和用于通过minimize
或leastsq
进行通用最小化的目标函数进行曲线拟合的函数。目标函数的签名如下:
def objective(params, *args):
其中params
是一个lmfit.Parameters
实例,您必须在函数中解包,而*args
是可选参数。此函数将返回数组-目标-在最小二乘意义上将最小化。
相反,用于创建曲线拟合模型的模型函数将具有类似的签名
def modelfunc(x, par1, par2, par3, ..., **kws):
其中x
是自变量,而par1
...将包含模型参数的值。模型函数将返回一个对数据进行建模的数组。
有许多示例使用目标函数和模型函数 https://github.com/lmfit/lmfit-py/tree/master/examples。要对数据建模,您可以
# define MODEL **not objective** function: returns the array to model the data
def sinedecay(x, amp, shift, omega, decay):
"""Model a decaying sine wave""" .
return amp * np.sin(x*omega + shift) * np.exp(-x*x*decay)
# create model:
smodel = Model(sinedecay)
# create a set of Parameters
params = smodel.make_params(amp=10, decay=0.1, shift=0, omega=3)
params.set('amp', min=0)
params.set('shift', min=-np.pi/2., max=np.pi/2)
# do fit
result = smodel.fit(data, params, x=x)