如何使用Python lmfit将参数的总和限制为一个值?

How to constrain a sum of parameters to one value with Python lmfit?

提问人:Stanley Scott 提问时间:6/4/2023 更新时间:6/6/2023 访问量:93

问:

我正在使用 python 来最小化具有三个变量的拟合函数的残差;和。我在这里提供了一个简化版本:lmfitAPS

from lmfit import minimize, Parameters
import numpy as np

# define model
def my_model(params, x):
    A = params['A']
    P = params['P']
    S = params['S']
    return A*x**2 + B*x + C


# define objective function
def residual(params, x, y, errs):
    return (y - my_model(params, x)) / errs


# import data
data = np.loadtxt('data/test.csv')
xs, ys, yerrs = data[0], data[1], data[2]


# initialise parameters
params = Parameters()
params.add('A', value=0.8,  vary=True,  min=0,  max=1)
params.add('P', value=0.15, vary=True,  min=0,  max=1)
params.add('S', value=0.05, vary=True,  min=0,  max=1)


# minimise objective function to find optimal parameters
lsq = minimize(my_model, params, args=(xs, ys, yerrs))

我的问题是,我怎样才能约束我的参数,使它们满足,同时仍然允许它们自由变化以最适合数据?也许是这样的话:A + P + S = 1
lsq = minimize(my_model, params, args=(xs, ys, yerrs), constraints=['A+P+S=1'])

我尝试使用附加参数,但这不能正确约束数据并且不满足条件 - 我不知道为什么。此外,此参数的设置似乎也被忽略了,它只是变化,使条件满足 的负值,允许大于 1。params.add('epsilon', expr='1 - A - P - S', min=0, max=0.0001)vary=FalseepsilonA + P + S

Python 约束曲线 拟合 LMFit Levenberg-Marquardt

评论


答:

0赞 M Newville 6/6/2023 #1

需要认识到的重要一点是,如果你想约束你的参数,使 A + P + S = 1,那么它们实际上并不是自由变化的。您有两个自由变量和一个受这两个变量约束的参数。我想你想做的是

params = Parameters()
params.add('A', value=0.8,  vary=True,  min=0,  max=1)
params.add('P', value=0.15, vary=True,  min=0,  max=1)
params.add('S', expr='1-A-P',  min=0,  max=1)

这几乎可以保证总和是 1 -- 我说几乎是因为所有参数上添加的边界可能会导致约束的边际违反。

评论

0赞 Stanley Scott 6/8/2023
谢谢。是否有任何标准程序可以遵循来选择哪个变量不能自由变化?我想到的也许是目标函数最敏感的那个?
0赞 M Newville 6/8/2023
嗯,我不知道有什么标准方法。但是,如果其中一个变量对残差有特别的尖锐或不稳定的影响,那么它应该是不允许自由变化的变量。也就是说,雅可比 (d_Residual / d_Variable) 是光滑的和相当抛物线的,确实使拟合变得更容易一些,所以如果很明显有一个不光滑的雅可比,最好将其作为约束。但是,我也要承认,我很少考虑这一点,只会限制最清楚或最容易表达为约束的那个。