为啥误差这么大?

Posted

技术标签:

【中文标题】为啥误差这么大?【英文标题】:Why are the errors so large?为什么误差这么大? 【发布时间】:2021-11-17 21:50:36 【问题描述】:

我正在尝试使用来自scripy.optimizecurve_fita*x**b+c 形式的幂律拟合到某些数据点。 这是 MWE:

import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

def func_powerlaw(x, m, c, c0):
    return c0 + x**m * c

x = np.array([1.05, 1.0,  0.95, 0.9,  0.85, 0.8,  0.75, 0.7,  0.65, 0.6,  0.55])
y = np.array([1.26, 1.24, 1.2,  1.17, 1.1,  1.01, 0.95, 0.84, 0.75, 0.71, 0.63])
dy = np.array([0.078]*11)

fig, (a1) = plt.subplots(ncols=1,figsize=(10,10))
a1.errorbar(x, y, yerr = dy, ls = '', marker='o')

popt, pcov = curve_fit(func_powerlaw, x, y, sigma = dy, p0 = [0.3, 1, 1], bounds=[(0.1, -2, -2), (0.9, 10, 2)], absolute_sigma=False, maxfev=10000, method = 'trf')
perr=np.sqrt(np.diag(pcov))

xp = np.linspace(x[0],x[-1], 100)
a1.plot(xp, func_powerlaw(xp, *popt), lw=3, zorder = 1, c = 'b')
print(popt, perr)

输出:[0.35609897 3.24929422 -2.] [0.47034928 3.9030258 3.90965249]

对于所有三个参数,误差都大于值估计本身。从经验来看,这不可能是正确的,因为这条线非常适合数据点。 即使我没有设置任何界限和/或初始猜测,值也会改变,但错误仍然太高。 唯一需要的边界是0.1<=m<=0.9。 我究竟做错了什么? 非常感谢任何帮助!

【问题讨论】:

不确定性dy 表示任何值y_i +/- dy 都与观察到的数据y 兼容。观测数据的大误差会导致拟合参数的大误差。尝试以下操作:for y in np.random.uniform(y - dy, y + dy, size=(25, len(y))): ...,然后对每个随机采样的y(在其不确定性边界内采样)执行拟合,但没有表明拟合过程存在错误(sigma)。然后记录生成的参数估计值 (popt) 并查看np.mean(popts), np.std(popts)。第二个值应与您的匹配值相匹配。 用盐的海洋来发表我的意见,因为我从来没有做过这种事情,但它可能会过度拟合吗? @a_guest 按照这个逻辑,不应该完全删除 sigma 以获得更好的拟合吗?因为似乎恰恰相反。 @chess_lover_6 我也尝试过lmfit,据我所知,它是curve_fit 的包装器,它打印了 χ^2 值。它们很糟糕,甚至不接近 1。所以我认为这不是因为过度拟合。 @George 首先,将sigmaabsolute_sigma=False 一起使用的值与absolute_sigma=False 一起使用没有任何效果,因为如文档中所述,如果False (默认),只有 sigma 值的相对大小很重要。尽管如此,这似乎与您手头的问题无关,因为当您完全删除sigma 时,这仍然会导致perr 很大。如果我理解正确,这是您的实际问题:生成的曲线非常适合数据点(例如从绘图或 R2 分数判断),但是报告的 perr 非常大。 【参考方案1】:

拟合参数中的误差大小部分取决于测量误差的大小(代码中的 dy)。正如您在图中看到的那样,sigma 相对于点的分散来说很大,因此各种曲线都可以拟合数据。 dy 值在这里是硬编码的,它们是真实值吗?尝试制作更小,看看它如何影响曲线拟合错误。而且它们在图中看起来像绝对 sigma,因此您应该将 absolute_sigma 标志设置为 True。

作为补充说明,如果您未在 sigma 参数中提供测量误差,则默认值为 1.0(在您的情况下非常大),而不是每个 y 值的 0.0。这就解释了为什么省略 sigma 会产生更大的拟合误差。

【讨论】:

dy 确实是真正的价值。如果 sigma 值是造成大错误的罪魁祸首,不应该完全删除它们会降低错误值吗?尝试这样做会大大增加错误值。将 absolute_sigma 值设置为 true 也是如此。 如果为sigma传入None(默认),每个y点使用默认的测量误差,即1.0。在您的情况下,这是一个很大的误差,因此拟合参数的误差很大。在这种情况下,默认值不是很有帮助! 尝试将测量误差设置为 0.01(例如),看看拟合效果如何。请记住,这些假设为 1 sigma 误差,因此如果测量值正态分布在真实值附近,则最佳拟合线应通过大约 2/3 的误差线。

以上是关于为啥误差这么大?的主要内容,如果未能解决你的问题,请参考以下文章

BP神经网络做手写数字识别误差较大

为啥我得到高 MAE(平均绝对误差)和 MSE(均方误差)与 MAPE(平均绝对百分比误差)相比?

我的手机GPS误差很大怎么回事?

为啥要在多元回归方程中加入误差项

为啥将误差乘以神经网络中 sigmoid 的导数?

线性回归模型 为啥要求随机误差的均值为0