【问题标题】:'TypeError: 'CompositeModel' object is not callable' when trying to fit a composite model'TypeError: 'CompositeModel' object is not callable' 尝试拟合复合模型时
【发布时间】:2020-03-07 15:33:10
【问题描述】:

我目前正在使用lmfit 分析一些光谱数据,特别是尝试拟合由高斯和线性模型组成的复合模型,多次(现在 4 次,可能需要拟合一些将来会更多),并且我不断收到上述错误。这是我当前的代码:

gausmodel = GaussianModel()
linemodel = LinearModel()

params = linemodel.make_params(intercept=40, slope=0)
params += gausmodel.make_params(cen=100, sigma=10, amplitude=100)

model = gausmodel + linemodel

x = pd.DataFrame(np.arange(0, 351), columns=['Pixel Position'])
df = pd.concat([x, intens], axis=1)

# Create models for fitting
peak1 = model(prefix='p1_')
peak2 = model(prefix='p2_')
peak3 = model(prefix='p3_')
peak4 = model(prefix='p4_')

# Set hints for start parameters
params = peak1.make_params()

params['p1_cen'].set(value=80, min=70, max=100)
params['p1_sigma'].set(value=10, min=5, max=20)
params['p1_amplitude'].set(value=80, min=50, max=100000)
params['p1_intercept'].set(value=40, min=30, max=55)
params['p1_slope'].set(value=1, min=0.00001, max=5)

params.update(peak2.make_params())

params['p2_center'].set(value=150, min=140, max=160)
params['p2_sigma'].set(value=10, min=5, max=20)
params['p2_amplitude'].set(value=80, min=50, max=100000)
params['p2_intercept'].set(value=40, min=30, max=55)
params['p2_slope'].set(value=1, min=0.00001, max=5)

params.update(peak3.make_params())

params['p3_center'].set(value=200, min=180, max=220)
params['p3_sigma'].set(value=10, min=5, max=20)
params['p3_amplitude'].set(value=100, min=50, max=100000)
params['p3_intercept'].set(value=40, min=30, max=55)
params['p3_slope'].set(value=1, min=0.00001, max=5)

params.update(peak4.make_params())

params['p4_center'].set(value=250, min=230, max=300)
params['p4_sigma'].set(value=10, min=5, max=20)
params['p4_amplitude'].set(value=100, min=50, max=100000)
params['p4_intercept'].set(value=40, min=30, max=55)
params['p4_slope'].set(value=1, min=0.00001, max=5)

# Define peak model
fit_model = peak1 + peak2 + peak3

# Start fitting
init = fit_model.eval(params, x=df)
result = fit_model.fit(df['Intensity'], params, x=df['Pixel Position'])

print(result.fit_report())

我实际上希望继续使用lmfit 而不是scipy,因为 lmfit 会返回一些我需要的有用统计信息,尤其是减少的卡方。

我的数据框只包含两列,一列是像素位置,另一列是强度,其中有 4 个峰值。

提前非常感谢!

【问题讨论】:

    标签: python-3.x pandas lmfit


    【解决方案1】:

    我认为您混淆了什么是模型类和什么是模型实例。此外,您不需要多行 - 两行加起来就是一行。

    我建议使用类似的东西:

    from lmfit.models import GaussianModel, LinearModel
    
    peak1 = GaussianModel(prefix='p1_')
    peak2 = GaussianModel(prefix='p2_')
    peak3 = GaussianModel(prefix='p3_')
    peak4 = GaussianModel(prefix='p4_')
    model = peak1 + peak2 + peak3 + peak4 + LinearModel()
    
    params = model.make_params(intercept=40, slope=0) 
    
    params['p1_center'].set(value=80, min=70, max=100)
    params['p1_sigma'].set(value=10, min=0)
    params['p1_amplitude'].set(value=80, min=0)
    
    params['p2_center'].set(value=150, min=140, max=160)
    params['p2_sigma'].set(value=10, min=0)
    params['p2_amplitude'].set(value=80, min=0)
    
    params['p3_center'].set(value=200, min=180, max=220)
    params['p3_sigma'].set(value=10, min=0)
    params['p3_amplitude'].set(value=100, min=0)
    
    params['p4_center'].set(value=250, min=230, max=300)
    params['p4_sigma'].set(value=10, min=0)
    params['p4_amplitude'].set(value=100, min=0)
    

    此外,在这里将 numpy 数组转换为数据帧确实没有多大意义——lmfit 只会将它们改回数组。

    x = p.arange(0, 351)
    init = model.eval(params, x=x)
    

    ...

    【讨论】:

    • 嗨!问题是我拥有的数据基本上有一个大的、通道可变的背景,这就是我想为每个高斯峰添加一个额外背景的原因。我能否澄清您的评论,即我“混淆了模型类和模型实例”,我认为我不理解那句话。但是感谢您对使用 numpy 数组作为 x 轴的评论!
    • 关于“混淆模型类与实例”:问题的标题有异常消息“CompositeModel is not callable”。而且您确实创建了复合模型的实例(使用“model=GaussianModel() + LinearModel()”),然后重复调用它(使用“peak1 = mode(prefix='p1_')”)。这确实会导致您看到的异常,因为模型的实例不可调用。相反,您应该创建一个模型的实例,然后使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    相关资源
    最近更新 更多