使用复合 PseudoVoigt 模型时出现 NameError

将复合 PseudoVoigt 模型与参数命名前缀结合使用时,出现 NameError 错误。


我几乎从上一个问题中复制了复合模型的示例,使用洛伦兹配置文件(使用 LMFIT 将多峰函数拟合到数据集)。这对我来说很好用,但洛伦兹线形状不是我想要的函数。


当我将 PseudoVoigtModel 用于单个峰时,我没有任何问题。此外,LorentzModel 与下面的代码一起工作正常(我也将它包含在代码中,以便您可以仔细检查/确认自己)。


from lmfit.models import LorentzianModel, PseudoVoigtModel

import numpy as np

import matplotlib.pyplot as plt


def 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 model



def 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() 函数中传递有关。


沧海一幻觉
浏览 271回答 1
1回答

缥缈止盈

最好找到并发布一个显示问题的最小示例,并且最好包含包括回溯在内的完整输出。例如,您会看到您遇到的问题:from lmfit.models import PseudoVoigtModelpref = '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,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;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():&nbsp; &nbsp; print(p)问题出现是因为没有名为fraction. 正如上面几行定义的那样,它被命名为f1_fraction.要解决这个问题,你应该改变的表达式pref+'height'也包括你pref需要的前缀字符串fraction,amplitude和sigma。或者:您可以删除您的提示,height因为无论如何这都会自动完成,并正确使用您提供的前缀。还:a) 绝对不鼓励使用参数提示来提供初始值。提示属于模型,不应依赖于任何特定的数据集。做一个Model作为通用的东西,然后给每个数据集做带初始值的参数。b) 不要将边界设置得太紧或基于初始值。界限(尤其是在参数提示中)应该用于防止参数变为非物理值,例如“为sigma负值毫无意义”,而不是因为定义模型的人认为“应该足够接近” . 让合身完成它的工作。如果您确实需要设置自定义边界,请按照数据集进行设置。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python