使用lmfit拟合多个数据集而无需编写目标函数

时间:2018-07-16 15:25:52

标签: python-2.7 lmfit

本主题描述如何使用lmfit适应多个数据集: Python and lmfit: How to fit multiple datasets with shared parameters?

但是,它使用用户编写的拟合/目标函数。

我想知道是否有可能使用lmfit来拟合多个数据集,而无需编写目标函数和模型类的model.fit()方法。

例如:假设我们要使用同一模型函数拟合多个(x,y)坐标数据集,以找到平均而言最适合所有数据的参数集。

import numpy as np 
from lmfit import Model, Parameters
from lmfit.models import GaussianModel

def gauss(x, amp, cen, sigma):
    return amp*np.exp(-(x-cen)**2/(2.*sigma**2))

x1= np.arange(0.,100.,0.1)
x2= np.arange(0.,100.,0.09)
y1= gauss(x1, 1.,50.,5.)+ np.random.normal(size=len(x1), scale=0.1)
y2= gauss(x2, 0.8,48.4.,4.5)+ np.random.normal(size=len(x2), scale=0.1)

mod= GaussianModel()
params= mod.make_params()

mod.fit([y1,y2], params, x= [x1, x2])

我猜是否有可能将数据以正确的类型传递给mod.fit。该文档只说mod.fit接受类似数组的数据输入。

我试图给它列表和数组。如果我将不同的数据集作为列表传递,则会出现ValueError:设置具有序列的数组元素

如果我传递数组,则会得到AttributeError:'numpy.ndarray'没有属性'exp'

那么我只是在尝试做一些不可能的事情还是做错了什么?

2 个答案:

答案 0 :(得分:0)

好吧,我认为答案是“有点”。 lmfit.Model类用于表示数据数组的模型。因此,如果您可以将多个数据集映射到一个numpy ndarray中(例如,使用np.concatenate),则可以通过为不同数据集构建子模型并以相同方式将它们串联来编写一个Model函数来表示这一点。

我认为您无法使用任何内置模型来做到这一点。我还认为,一旦您开始编写复杂的模型函数,对编写目标函数而言就不是很大的进步。即是

def model_function(x, a, b, c):
   ### do some calculation with x, a, b, c values
   result = a + x*b + x*x*c
   return result

可能成为

def objective_function(params, x, data):
     vals = params.valuesdict()
     return data - model_function(x, vals['a'], vals['b'], vals['c'])

如果do_calc()做的事情很复杂,则拆包参数和减去数据的额外负担将很小。而且,尤其是如果某些参数将用于多个数据集,而某些参数仅用于特定数据集,则必须在模型函数或目标函数中进行管理。在链接到的示例中,我的答案包括对数据集的循环,按名称为每个数据集选择参数。您可能想要做类似的事情。您可以通过在模型函数中将其视为连接的数据集来建模来实现此目的,但是我不确定这样做是否会带来很多好处。

答案 1 :(得分:0)

我发现了问题。实际上,model.fit()可以很好地处理多个数据集的数组并执行适当的拟合。带有多个数据集的model.fit()的正确调用将是:

widget.value = "My default value";

原始代码中的问题实际上在于我的数据集长度不同。但是我完全不确定如何以最优雅的方式处理此问题?