为了账号安全,请及时绑定邮箱和手机立即绑定

使用复合 PseudoVoigt 模型时出现 NameError

使用复合 PseudoVoigt 模型时出现 NameError

沧海一幻觉 2021-12-29 20:45:35
将复合 PseudoVoigt 模型与参数命名前缀结合使用时,出现 NameError 错误。我几乎从上一个问题中复制了复合模型的示例,使用洛伦兹配置文件(使用 LMFIT 将多峰函数拟合到数据集)。这对我来说很好用,但洛伦兹线形状不是我想要的函数。当我将 PseudoVoigtModel 用于单个峰时,我没有任何问题。此外,LorentzModel 与下面的代码一起工作正常(我也将它包含在代码中,以便您可以仔细检查/确认自己)。from lmfit.models import LorentzianModel, PseudoVoigtModelimport numpy as npimport matplotlib.pyplot as pltdef make_model_L(num):    pref = "f{0}_".format(num)    model = LorentzianModel(prefix = pref)    model.set_param_hint(pref+'amplitude', value=amplitude[num], min=0, max=5*amplitude[num])    model.set_param_hint(pref+'center', value=center[num], min=center[num]-0.5, max=center[num]+0.5)    model.set_param_hint(pref+'sigma', value=width[num], min=0, max=2)    return modeldef make_model_V(num):    pref = "f{0}_".format(num)    model = PseudoVoigtModel(prefix = pref)    print('before',model.param_names)    model.set_param_hint(pref+'fraction',value = 0.7, vary = False)    model.set_param_hint(pref+'amplitude', value=amplitude[num], min=0, max=5*amplitude[num])    model.set_param_hint(pref+'center', value=center[num], min=center[num]-0.5, max=center[num]+0.5)    model.set_param_hint(pref+'fwhm', value=3, min=3/5, max=3*5)    model.set_param_hint(pref+'sigma', value=1, min=0, max=2)    model.set_param_hint(pref+'height', value=1, min=-np.inf, max=np.inf, expr='(((1-fraction)*amplitude)/(sigma*sqrt(pi/log(2)))+(fraction*amplitude)/(pi*sigma))')    print(model.param_names)    return model我收到的错误消息:NameError <_ast.Module object at 0x7f562524dbe0> ^^^ name 'fraction' 未定义NameError: at expr='<_ast.Module object at 0x7f562524dbe0>'我没有包括 TraceBack。它以“out=mod.fit(y, x=x, method='leastsq')”开始,以“~/anaconda3/lib/python3.6/site-packages/asteval/asteval.py in raise_exception(self , 节点, exc, msg, expr, lineno)"如前所述,使用 LorentzianModel 一切正常,我得到了合身(不是很好,但这是由于测试数据)。我不是很精通 python,所以我不能真正就问题可能是什么给出明智的提示。但是,我怀疑它与分数的命名以及它如何在 lmfit.fit() 函数中传递有关。
查看完整描述

1 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

最好找到并发布一个显示问题的最小示例,并且最好包含包括回溯在内的完整输出。


例如,您会看到您遇到的问题:


from lmfit.models import PseudoVoigtModel


pref = 'f1_'

model = PseudoVoigtModel(prefix = pref)

print('before',model.param_names)

model.set_param_hint(pref+'fraction',value = 0.7, vary = False)

model.set_param_hint(pref+'amplitude', value=2, min=0, max=5)

model.set_param_hint(pref+'center', value=0, min=-0.5, max=0.5)

model.set_param_hint(pref+'fwhm', value=3, min=3/5, max=3*5)

model.set_param_hint(pref+'sigma', value=1, min=0, max=2)

# suspect line:

model.set_param_hint(pref+'height', value=1, min=-np.inf, max=np.inf,

                     expr='(((1-fraction)*amplitude)/(sigma*sqrt(pi/log(2)))+(fraction*amplitude)/(pi*sigma))')


print(model.param_names)

params = model.make_params()

for p in params.values():

    print(p)

问题出现是因为没有名为fraction. 正如上面几行定义的那样,它被命名为f1_fraction.


要解决这个问题,你应该改变的表达式pref+'height'也包括你pref需要的前缀字符串fraction,amplitude和sigma。


或者:您可以删除您的提示,height因为无论如何这都会自动完成,并正确使用您提供的前缀。


还:


a) 绝对不鼓励使用参数提示来提供初始值。提示属于模型,不应依赖于任何特定的数据集。做一个Model作为通用的东西,然后给每个数据集做带初始值的参数。


b) 不要将边界设置得太紧或基于初始值。界限(尤其是在参数提示中)应该用于防止参数变为非物理值,例如“为sigma负值毫无意义”,而不是因为定义模型的人认为“应该足够接近” . 让合身完成它的工作。如果您确实需要设置自定义边界,请按照数据集进行设置。


查看完整回答
反对 回复 2021-12-29
  • 1 回答
  • 0 关注
  • 270 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信