在lmfit中考虑到实验误差

问题描述 投票:0回答:1

我正在努力实现 lmfit 到我的试衣程序中,而我在定义错误时遇到了问题。我的前提是,我在这个平台上阅读了以前关于这个话题的问题,我也翻阅了文档,但我的一些疑惑还是存在的。

以下是一个完整的、最基本的例子,我想达到的目的。

import corner
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import scipy as sp
import lmfit


font = {'fontname':'candara', "fontweight":"light"}
plt.style.use('ggplot')
plt.rcParams["figure.figsize"] = (8,4)
ax_fit_kws = dict(xlim=(0,0.12), ylim=(0.5,1.1))
ax_res_kws = dict(xlim=(0,0.12), ylim=(-0.1,0.1))

def mono_exp(SL_array, a, b):
    model = a * np.exp(-b * SL_array)
    return model
model = lmfit.Model(mono_exp)

SL_array = np.array((0.030, 0.040, 0.060, 0.080, 0.10))
data= np.array((1., 0.9524336, 0.92452666, 0.87995659, 0.82845576))
errs = np.array((0.00029904, 0.00049384, 0.00076344, 0.00053886, 0.00066012))

params = model.make_params(a=0, b=0)

result = model.fit(data=data, params=params, SL_array=SL_array, method="Nelder", markersize=10, weights=errs)

lmfit.report_fit(result)
result.plot(yerr = errs, ax_fit_kws=ax_fit_kws, ax_res_kws=ax_res_kws)

emcee_kws = dict(steps=400, burn=30, thin=20, is_weighted=False,
                 progress=True)
emcee_params = result.params.copy()
emcee_params.add('__lnsigma', value=np.log(0.1), min=np.log(0.001), max=np.log(2.0))
result_emcee = model.fit(data=data, SL_array=SL_array, params=emcee_params, method='emcee',
                         nan_policy='omit', fit_kws=emcee_kws)

lmfit.report_fit(result_emcee)

ax = plt.plot(SL_array, model.eval(params=result.params, SL_array=SL_array), label='Nelder', zorder=100)
result_emcee.plot_fit(ax=ax, data_kws=dict(color='gray', markersize=10), yerr = errs)
emcee_corner = corner.corner(result_emcee.flatchain, labels=result_emcee.var_names,
                             truths=list(result_emcee.params.valuesdict().values()))
plt.show()

我的问题比较简单。我想让初始的... Nelder 拟合程序,以考虑到 errs 数组作为错误在 data 数组(这是我实验确定的点)。我不确定调用 weights=errs 实现了这个目标。我已经尝试了这里实现的解决方案。我如何在lmfit最小二乘法迷你仿真中加入数据的误差 以及lmfit中conf_interval2d函数的误差是什么?但我无法使其工作。

另一个我不太清楚的问题是:在lmfit中的conf_interval2d函数中是否包含了 emcee 我的拟合度的一部分,考虑到了来自的残差。Nelder 惯例?

非常感谢!

编辑

经过更多的研究,我现在认为,在调用权重的时候,我实际上应该给与 1/err. 通过实施这一变化,并应用 scale_covar=False 如上所述(如何正确获取lmfit中的错误?),同时人为地增加误差值(例如,故意乘以 errs 数组的100倍),我确实得到了拟合参数误差大幅增加,这是一个预期的行为。简而言之。result = model.fit(data=data, params=params, SL_array=SL_array, method="Nelder", markersize=10, weights=errs) 被改成了 result = model.fit(data=data, params=params, SL_array=SL_array, method="Nelder", markersize=10, weights=1/errs). 这是否正确?

我还是比较迷惑,关于 emcee 在我的例子中。

python-3.x curve-fitting lmfit
1个回答
1
投票

你在编辑中说的是正确的:你想用 weights=1./err 的余量进行适当加权。datamodel 由数据的不确定性。err.

你可能想在你的调用中使用同样的方法来实现。model.fit(..., method='emcee') 也。

我应该说,使用 emceelmfit 是相当混乱的,并给人留下了不幸的印象,即它正在做一个配合。这根本不是事实,因为 emcee (实际上,MCMC作为一种方法)并不能真正做到 "系统地细化参数值以找到一个改进的解 "的意义上的拟合。 它所做的是在输入参数值附近的参数空间进行探索(恰好是来自于 Nelder 方法).这种探索可能会发现(更像是 "偶然发现 "而不是 "寻求")一个改进的解决方案,结果将反映出它的探索。

© www.soinside.com 2019 - 2024. All rights reserved.