Python lmfit 自定义模型:设置固定参数和分配前缀
Python lmfit custom models: set fixed parameter and assigning prefix
我有 2 个关于 lmfit 包中的参数的问题。
1.
有没有办法为自定义模型预先设置参数值?
例如
def my_cust(x,A,b):
return A*x + b
def gaussian(x, amp, cen, wid):
return (1.2345*amp/(sqrt(2*pi)*wid)) * exp(-(x-cen)**2 /wid)
mod = Model(my_cust) + Model(gaussian)
pars = mod.make_params(A=11.78,b=25,amp=2000,cen=109.5,wid=17) #initialize all the parameters
results = mod.fit(y,pars,x=x)
倒数第二行,例如amp=2000
初始化参数amp
。如果我想在 内置 模型中修复此参数(例如 this one):
params = model.make_params()
params['g1_amplitude'].set(2000, vary=False)
问题 1
是否可以在 mod.fit()
行或 自定义的其他地方 修复 参数 amp
的值 2000 型号?
2.
我正在尝试为自定义复合模型分配前缀,如下所示:
cust_combination_mod = Model(my_cust, prefix='lin_') + Model(gaussian, prefix='g1_')
当我尝试上述行时,我得到:
File "build\bdist.win-amd64\egg\lmfit\model.py", line 541, in fit
File "build\bdist.win-amd64\egg\lmfit\model.py", line 747, in fit
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1242, in minimize
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1072, in leastsq
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 377, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 26, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 371, in __residual
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1432, in _nan_policy
ValueError: The input contains nan values
如果有很多自定义模型,那么初始化 mod.make_params()
中的所有参数(如我在上面的 1. 中所示)可能会很繁琐。这个问题似乎在这里讨论 (1,2)
但它们并没有真正说明如何实际为复合模型的单独组件分配前缀。
问题二
是否可以为 lmfit
中的复合自定义模型分配前缀?
Q1:您可以在定义模型时为自定义模型设置默认值:
>>> def my_cust(x, a=1.0, b=2.0):
... return a*x + b
>>> lmodel = Model(my_cust)
>>> params = lmodel.make_params()
>>> params
Parameters([('a', <Parameter 'a', 1.0, bounds=[-inf:inf]>), ('b', <Parameter 'b', 2.0, bounds=[-inf:inf]>)])
并且您可以在创建参数后对其进行修复:
>>> params['a].vary = False
您还可以在模型上设置一个 "parameter hint" 以告诉属性在创建参数时分配:
>>> lmodel.set_param_hint('a', vary=False)
>>> lmodel.set_param_hint('b', min=0)
>>> params = lmodel.make_params()
>>> params
Parameters([('a', <Parameter 'a', value=1.0 (fixed), bounds=[-inf:inf]>), ('b', <Parameter 'b', 2.0, bounds=[0:inf]>)])
Q2:做
>>> comp_model = Model(my_cust, prefix='lin_') + Model(gaussian, prefix='g1_')
应该有效(而且,它对我有用)。为此生成的参数将具有适当的前缀,并且应该在 Model.make_params
:
中引用 with prefix
>>> params = comp_model.make_params(g1_amp=9, g1_cen=2.0, g1_wid=0.5)
>>> for name, par in params.items():
... print(name, par)
...
('lin_a', <Parameter 'lin_a', 1.0, bounds=[-inf:inf]>)
('lin_b', <Parameter 'lin_b', 2.0, bounds=[-inf:inf]>)
('g1_amp', <Parameter 'g1_amp', 9, bounds=[-inf:inf]>)
('g1_cen', <Parameter 'g1_cen', 2.0, bounds=[-inf:inf]>)
('g1_wid', <Parameter 'g1_wid', 0.5, bounds=[-inf:inf]>)
如果你想保留上面设置的参数提示,你应该制作带有前缀的自定义模型,设置参数提示,然后制作自定义模型:
>>> lmodel = Model(my_cust, prefix='lin_')
>>> lmodel.set_param_hint('a', vary=False)
>>> lmodel.set_param_hint('b', min=0)
>>> comp = lmodel + Model(gauss, prefix='g1_')
>>> params = comp.make_params(g1_amp=9.0, g1_cen=2.0, g1_wid=0.5)
>>> for name, par in params.items():
... print(name, par)
...
('lin_a', <Parameter 'lin_a', value=1.0 (fixed), bounds=[-inf:inf]>)
('lin_b', <Parameter 'lin_b', 2.0, bounds=[0:inf]>)
('g1_amp', <Parameter 'g1_amp', 9.0, bounds=[-inf:inf]>)
('g1_cen', <Parameter 'g1_cen', 2.0, bounds=[-inf:inf]>)
('g1_wid', <Parameter 'g1_wid', 0.5, bounds=[-inf:inf]>)
我不确定 NaN 异常是从哪里来的。也许是因为没有为参数提供初始值(这可能会导致默认为 -inf)或者因为正在建模的数据中存在 NaN?
我有 2 个关于 lmfit 包中的参数的问题。
1.
有没有办法为自定义模型预先设置参数值?
例如
def my_cust(x,A,b):
return A*x + b
def gaussian(x, amp, cen, wid):
return (1.2345*amp/(sqrt(2*pi)*wid)) * exp(-(x-cen)**2 /wid)
mod = Model(my_cust) + Model(gaussian)
pars = mod.make_params(A=11.78,b=25,amp=2000,cen=109.5,wid=17) #initialize all the parameters
results = mod.fit(y,pars,x=x)
倒数第二行,例如amp=2000
初始化参数amp
。如果我想在 内置 模型中修复此参数(例如 this one):
params = model.make_params()
params['g1_amplitude'].set(2000, vary=False)
问题 1
是否可以在 mod.fit()
行或 自定义的其他地方 修复 参数 amp
的值 2000 型号?
2.
我正在尝试为自定义复合模型分配前缀,如下所示:
cust_combination_mod = Model(my_cust, prefix='lin_') + Model(gaussian, prefix='g1_')
当我尝试上述行时,我得到:
File "build\bdist.win-amd64\egg\lmfit\model.py", line 541, in fit
File "build\bdist.win-amd64\egg\lmfit\model.py", line 747, in fit
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1242, in minimize
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1072, in leastsq
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 377, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 26, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 371, in __residual
File "build\bdist.win-amd64\egg\lmfit\minimizer.py", line 1432, in _nan_policy
ValueError: The input contains nan values
如果有很多自定义模型,那么初始化 mod.make_params()
中的所有参数(如我在上面的 1. 中所示)可能会很繁琐。这个问题似乎在这里讨论 (1,2)
但它们并没有真正说明如何实际为复合模型的单独组件分配前缀。
问题二
是否可以为 lmfit
中的复合自定义模型分配前缀?
Q1:您可以在定义模型时为自定义模型设置默认值:
>>> def my_cust(x, a=1.0, b=2.0):
... return a*x + b
>>> lmodel = Model(my_cust)
>>> params = lmodel.make_params()
>>> params
Parameters([('a', <Parameter 'a', 1.0, bounds=[-inf:inf]>), ('b', <Parameter 'b', 2.0, bounds=[-inf:inf]>)])
并且您可以在创建参数后对其进行修复:
>>> params['a].vary = False
您还可以在模型上设置一个 "parameter hint" 以告诉属性在创建参数时分配:
>>> lmodel.set_param_hint('a', vary=False)
>>> lmodel.set_param_hint('b', min=0)
>>> params = lmodel.make_params()
>>> params
Parameters([('a', <Parameter 'a', value=1.0 (fixed), bounds=[-inf:inf]>), ('b', <Parameter 'b', 2.0, bounds=[0:inf]>)])
Q2:做
>>> comp_model = Model(my_cust, prefix='lin_') + Model(gaussian, prefix='g1_')
应该有效(而且,它对我有用)。为此生成的参数将具有适当的前缀,并且应该在 Model.make_params
:
>>> params = comp_model.make_params(g1_amp=9, g1_cen=2.0, g1_wid=0.5)
>>> for name, par in params.items():
... print(name, par)
...
('lin_a', <Parameter 'lin_a', 1.0, bounds=[-inf:inf]>)
('lin_b', <Parameter 'lin_b', 2.0, bounds=[-inf:inf]>)
('g1_amp', <Parameter 'g1_amp', 9, bounds=[-inf:inf]>)
('g1_cen', <Parameter 'g1_cen', 2.0, bounds=[-inf:inf]>)
('g1_wid', <Parameter 'g1_wid', 0.5, bounds=[-inf:inf]>)
如果你想保留上面设置的参数提示,你应该制作带有前缀的自定义模型,设置参数提示,然后制作自定义模型:
>>> lmodel = Model(my_cust, prefix='lin_')
>>> lmodel.set_param_hint('a', vary=False)
>>> lmodel.set_param_hint('b', min=0)
>>> comp = lmodel + Model(gauss, prefix='g1_')
>>> params = comp.make_params(g1_amp=9.0, g1_cen=2.0, g1_wid=0.5)
>>> for name, par in params.items():
... print(name, par)
...
('lin_a', <Parameter 'lin_a', value=1.0 (fixed), bounds=[-inf:inf]>)
('lin_b', <Parameter 'lin_b', 2.0, bounds=[0:inf]>)
('g1_amp', <Parameter 'g1_amp', 9.0, bounds=[-inf:inf]>)
('g1_cen', <Parameter 'g1_cen', 2.0, bounds=[-inf:inf]>)
('g1_wid', <Parameter 'g1_wid', 0.5, bounds=[-inf:inf]>)
我不确定 NaN 异常是从哪里来的。也许是因为没有为参数提供初始值(这可能会导致默认为 -inf)或者因为正在建模的数据中存在 NaN?