Python lmfit拟合得到极小卡方值,如何正确对残差进行缩放?
问题原因
你现在得到极小卡方是因为默认拟合采用无权重最小二乘,默认所有数据点的测量误差σ=1,而你的光谱y值本身在1e-15量级,残差平方后量级极低,所以卡方计算结果严重偏离合理范围,参数不确定度也未校准。以下是正确缩放残差的具体操作步骤:
具体操作步骤
分两种场景处理:
场景1:可获取逐点测量误差σ
如果能通过仪器参数、重复测量得到每个数据点对应的测量误差σ_i(长度和y一致),直接在拟合时传入权重参数即可:
- 权重取值为
1/σ_i,和lmfit的fit方法匹配,内部计算逻辑正好符合卡方定义χ²=Σ[(y_i - 模型值_i)/σ_i]^2 - 修改后的拟合代码如下:
# sigma为你计算得到的逐点测量误差数组,长度与y相同 result = mod.fit(y, pars, x=x, weights=1/sigma)
此时输出的卡方、约化卡方、参数不确定度都是经过正确缩放的结果。
常见误差估算参考:光谱测量如果是光子散粒噪声主导,σ_i=√(y_i),可以直接传入weights=1/np.sqrt(y),不需要额外测量误差。
场景2:无可用测量误差数据
如果无法获取逐点误差,用初始拟合残差估算全局误差做缩放,这也是官方文档提到的通用缩放方案:
- 先运行一次无权重的初始拟合,得到残差结果
init_result = mod.fit(y, pars, x=x)
- 用初始拟合的残差计算全局误差估计值
import numpy as np sigma_est = np.std(init_result.residual)
- 用估算的全局误差作为权重,重新运行拟合
result = mod.fit(y, pars, x=x, weights=1/sigma_est)
重新拟合后输出的约化卡方会接近1,参数不确定度也完成了正确缩放。
内容的提问来源于stack exchange,提问作者rbaer
相关产品推荐
相关产品推荐

