我正在使用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个数据图表进行全局拟合。问题是一些参数没有被拟合(变化=无),是已知量,并且在所有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分钟)。此外,拟合曲线对于所有图形都是相同的,而我希望它使用已知参数拟合每个局部图形并且仅适合全局参数。
我想问我是否正确地做到了这一点?我明白为什么minim()需要对y_data的引用进行拟合,但为什么fcn2min()需要y_data作为输入?我的拟合程序可能会混淆它是否适合y_data或known_params数组?有没有更好的方法通过lmfit来做到这一点,还是我应该寻找另一个数字包?
答案 0 :(得分:0)
如果没有实际的示例代码,获取所有细节有点困难,但我可以尝试解决您提出的一些主题。
首先,fcn2min()
需要传递y_data
(和x_data
这个数组)数组,因为从minimize()
(和底层求解器)的角度来看,它期望目标函数在给定可变参数的情况下使数组返回最小化 - 它没有考虑"数据"一点都不对于拟合数据,您的目标函数可能很好
return y_data - model_for_y(params, x_data)
但是拟合算法关注参数值如何改变要最小化的数组,而不是如何计算该数组。它被称为"最小化()",而不是" fit()"。
其次,如果我理解正确,你有很多(36)个数据集都具有大致相同的模型,虽然每个数据集的某些参数值可能不同,但是其他一些数据集应该在所有数据集之间共享
使用lmfit,最好的方法是做一个全局适合。创建一个Parameters()对象,每个模型有36组参数。例如,如果您拟合36个数据集,每个数据集都具有类似峰值的函数,每个数据集都有参数" amp"," center"," sigma",&# 34; offset",您可以创建名为amp01
,center01
,...,sigma36
,offset36
的参数。是的,这可能是适合的许多参数。
然后,在您的目标函数中,循环遍历每个数据集,仅使用适当的参数对该数据集进行建模,为36个数据集构建36个单独的残差。最后,连接这些以使最大化的数组最小化。
如果36 * nparameters_per_dataset参数中的每一个都是独立变量,那么你可能在运行36个单独拟合方面获得了很多。但是,如果你可以断言某些变量对于所有数据集都具有相同的值,那么这些变量就不会是独立的。我认为这就是你要做的事情。
让我们说你知道"抵消"对于所有数据集都是相同的。您只需制作1 offset
参数并将其用于所有数据集,因此不能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函数。
希望有所帮助。