python lmfit,不可修改的数组作为模型的参数 class?
python lmfit, non-modifiable array as parameter for Model class?
我只是想拟合一个函数来检索两个数组之间的相关 Pearson 系数。这两个数组作为输入参数传递给函数,但它们不会改变。对于函数,它们应该被解释为常量。我找到了一个参数选项,可以固定一个参数,即它不能变化,但它仅适用于标量值。
当我调用 Model.make_params() 时,模型 Class 会尝试检查这些数组是否低于或高于 minimum/maximum。不需要此评估,因为它们是常量。
我的函数:
def __lin_iteration2__(xref, yref_scaled, xobs, yobs, slope, offset, verbose=False, niter=None):
Acal = 1 + (offset + slope*xref)/xref
xr_new = xref * Acal
obs_interp1d = interp1d(xobs, yobs, kind='cubic')
yobs_new = scale_vector(obs_interp1d(xr_new))
rho = Pearson(yref_scaled, yobs_new)
return rho
其中xref、yref_scaled、xobs、yobs是不变的数组,即常量。 'interp1d'是来自scipy.interpolate的插值算子,'scale_vector'在-1和1之间缩放向量,'Pearson'计算Pearson相关系数。
我给谁设置了模型class:
m = Model(corr.__lin_iteration3__)
par = m.make_params(yref_scaled = corr.yref_scaled, \
obs_interp1d=corr.obs_interp1d, offset=0, scale=0)
par['yref_scaled'].vary = False
par['obs_interp1d'].vary = False
r = m.fit
我得到的错误(就在我调用模型Class的'make_params'函数时的第二行):
Traceback (most recent call last):
File "<ipython-input-3-c8f6550e831e>", line 1, in <module>
runfile('/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py', wdir='/home/andrey/Noveltis/tests/new_correl_sp')
File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile
execfile(filename, namespace)
File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py", line 264, in <module>
obs_interp1d=corr.obs_interp1d, offset=0, scale=0)
File "/usr/lib/python3/dist-packages/lmfit/model.py", line 401, in make_params
params.add(par)
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 338, in add
self.__setitem__(name.name, name)
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 145, in __setitem__
self._asteval.symtable[key] = par.value
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 801, in value
return self._getval()
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 786, in _getval
if self._val > self.max:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
在 lmfit
中,模型函数的参数应为标量、浮点参数值,但 "independent variables" 除外,它可以是任何 python 对象。默认情况下,第一个函数参数被假定为独立变量,任何具有非数字默认值的关键字参数也是如此。但是,您可以在创建模型时指定哪些参数是自变量(可以有多个)。
我想你想要的是:
m = Model(corr.__lin_iteration3__, independent_vars=['xref', 'yref_scaled', 'xobs', 'yobs'])
但也:你也可以传递任何 Python 对象,所以你可以将你的 ref 和 obs 数据打包到其他结构中并做类似
def lin_iteration(Data, slope, offset, verbose=False, niter=None):
Acal = 1 + (offset + slope*Data['xref'])/Data['xref']
xr_new = Data['xref'] * Acal
# or maybe that would be clearer as just
# xr_new = offset + (1+slope)* Data['xref']
obs_interp1d = interp1d(Data['xobs'], Data['yobs'], kind='cubic')
yobs_new = scale_vector(obs_interp1d(xr_new))
rho = Pearson(Data['yref_scaled'], yobs_new)
return rho
和
m = Model(lin_iteration)
par = m.make_params(offset=0, scale=0)
Data = {'xref': xref, 'yref_scaled': yref_scaled, 'xobs': xobs, 'yobs': yobs}
result = m.fit(Data, params)
当然,这一切都未经测试,但它可能会让您的生活更轻松...
我只是想拟合一个函数来检索两个数组之间的相关 Pearson 系数。这两个数组作为输入参数传递给函数,但它们不会改变。对于函数,它们应该被解释为常量。我找到了一个参数选项,可以固定一个参数,即它不能变化,但它仅适用于标量值。
当我调用 Model.make_params() 时,模型 Class 会尝试检查这些数组是否低于或高于 minimum/maximum。不需要此评估,因为它们是常量。
我的函数:
def __lin_iteration2__(xref, yref_scaled, xobs, yobs, slope, offset, verbose=False, niter=None):
Acal = 1 + (offset + slope*xref)/xref
xr_new = xref * Acal
obs_interp1d = interp1d(xobs, yobs, kind='cubic')
yobs_new = scale_vector(obs_interp1d(xr_new))
rho = Pearson(yref_scaled, yobs_new)
return rho
其中xref、yref_scaled、xobs、yobs是不变的数组,即常量。 'interp1d'是来自scipy.interpolate的插值算子,'scale_vector'在-1和1之间缩放向量,'Pearson'计算Pearson相关系数。
我给谁设置了模型class:
m = Model(corr.__lin_iteration3__)
par = m.make_params(yref_scaled = corr.yref_scaled, \
obs_interp1d=corr.obs_interp1d, offset=0, scale=0)
par['yref_scaled'].vary = False
par['obs_interp1d'].vary = False
r = m.fit
我得到的错误(就在我调用模型Class的'make_params'函数时的第二行):
Traceback (most recent call last):
File "<ipython-input-3-c8f6550e831e>", line 1, in <module>
runfile('/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py', wdir='/home/andrey/Noveltis/tests/new_correl_sp')
File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile
execfile(filename, namespace)
File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/andrey/Noveltis/tests/new_correl_sp/new_correl.py", line 264, in <module>
obs_interp1d=corr.obs_interp1d, offset=0, scale=0)
File "/usr/lib/python3/dist-packages/lmfit/model.py", line 401, in make_params
params.add(par)
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 338, in add
self.__setitem__(name.name, name)
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 145, in __setitem__
self._asteval.symtable[key] = par.value
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 801, in value
return self._getval()
File "/usr/lib/python3/dist-packages/lmfit/parameter.py", line 786, in _getval
if self._val > self.max:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
在 lmfit
中,模型函数的参数应为标量、浮点参数值,但 "independent variables" 除外,它可以是任何 python 对象。默认情况下,第一个函数参数被假定为独立变量,任何具有非数字默认值的关键字参数也是如此。但是,您可以在创建模型时指定哪些参数是自变量(可以有多个)。
我想你想要的是:
m = Model(corr.__lin_iteration3__, independent_vars=['xref', 'yref_scaled', 'xobs', 'yobs'])
但也:你也可以传递任何 Python 对象,所以你可以将你的 ref 和 obs 数据打包到其他结构中并做类似
def lin_iteration(Data, slope, offset, verbose=False, niter=None):
Acal = 1 + (offset + slope*Data['xref'])/Data['xref']
xr_new = Data['xref'] * Acal
# or maybe that would be clearer as just
# xr_new = offset + (1+slope)* Data['xref']
obs_interp1d = interp1d(Data['xobs'], Data['yobs'], kind='cubic')
yobs_new = scale_vector(obs_interp1d(xr_new))
rho = Pearson(Data['yref_scaled'], yobs_new)
return rho
和
m = Model(lin_iteration)
par = m.make_params(offset=0, scale=0)
Data = {'xref': xref, 'yref_scaled': yref_scaled, 'xobs': xobs, 'yobs': yobs}
result = m.fit(Data, params)
当然,这一切都未经测试,但它可能会让您的生活更轻松...