0

我正在使用 lmfit python 包https://lmfit.github.io/lmfit-py/在某些参数的某些允许变化范围内将数据拟合到指定的非线性函数(这主要是我发现 lmfit 有吸引力的原因)。

通常,lmfit 的两行重要代码是:

def fcn2min(params, x_data, y_data):

result = minimize(fcn2min, params, args=(x_data, y_data))

我的应用程序是对 36 个数据图执行全局拟合。问题是一些参数没有被拟合(vary=None),是已知的数量,并且在所有 36 个图表中都不同,但在它们自己的图表中保持不变。目前,我正在尝试实现以下语法,以便将这些已知参数与其关联的 x_data 和 y_data 点一起传递。

def fcn2min(params, x_data, y_data, known_params):

result = minimize(fcn2min, params, args=(x_data, y_data, known_params))

这里 x_data、y_data 和 known_params 是长度相同的数组。x_data 和 y_data 由所有 36 个图的单个数组组成,并且 known_params 是一个三列数组,其中包含在每个图中固定的那些参数的重复条目。

目前程序运行速度很慢(直到执行完成 30 分钟)。同样,目前所有图的拟合曲线都是相同的,而我希望它用已知参数拟合每个局部图并仅拟合全局参数。

我想问一下我这样做是否正确?我明白为什么 minimize() 需要引用要拟合的 y_data,但为什么 fcn2min() 需要 y_data 作为输入?我的拟合程序是否会混淆它是否拟合 y_data 或 known_params 数组?有没有更好的方法通过 lmfit 做到这一点,或者我应该寻找另一个数字包?

4

1 回答 1

0

如果没有实际的示例代码,很难获得所有细节,但我可以尝试解决您提出的一些主题。

首先,fcn2min()需要传递y_data(以及x_data就此而言)数组,因为从(和底层求解器)的角度来看minimize(),它期望目标函数返回在给定变量参数的情况下最小化的数组——它不认为关于“数据”。对于拟合数据,您的目标函数很可能是 return y_data - model_for_y(params, x_data)

但是拟合算法关心的是参数 vales 如何改变要最小化的数组,而不是如何计算该数组。它被称为“最小化()”,而不是“适合()”。

其次,如果我理解正确,您有许多 (36) 个数据集,它们都具有大致相同的模型,虽然每个数据集的某些参数值可能不同,但其他一些参数值应该在所有数据集之间共享。

使用 lmfit,最好的方法是进行一次全局拟合。为每个模型创建一个具有 36 组参数的 Parameters() 对象。例如,如果您要拟合 36 个数据集,每个数据集都有一个类似峰值的函数,每个函数都有参数“amp”、“center”、“sigma”、“offset”,您可以将参数命名为amp01, center01, ..., sigma36, offset36。是的,这可能是适合的许多参数。

然后,在您的目标函数中,循环遍历每个数据集,仅使用适当的参数对该数据集进行建模,为 36 个数据集构建 36 个单独的残差。最后,将它们连接起来以提供一个非常大的数组以最小化。

如果 36*nparameters_per_dataset 参数中的每一个都是自变量,那么您可能没有比运行 36 个单独的拟合获得太多收益。但是,如果您可以断言某些变量对于所有数据集都具有相同的值,那么这些拟合将不是独立的。我认为这就是你想要做的。

假设您知道所有数据集的“偏移量”都是相同的。您可以只制作 1 offsetParameter 并将其用于所有数据集,所以没有offset01... offest36,只有 1 offset

为了更灵活,您可以定义offset01, ..., offset36,但使用 lmfit 约束来绑定它们的值

params = Parameters() params.add('offset01', value=0, vary=True) params.add('offset02', expr='offset01') params.add('offset03', expr='offset01') ...

使用这样的定义,offset01会有所不同,offset2并且offset03将具有相同的价值offset01——它们不会是独立的,而是受约束的。约束表达式可能更复杂,包括多个参数名称以及许多 Python 和 numpy 函数。

希望有帮助。

于 2016-07-13T03:01:19.753 回答