线型拟合的置信带绘制

在数据分析过程中,我们经常会遇到线型拟合问题。标准的做法是用最小二乘法(least-squares method)来计算相关系数,用协方差矩阵(covariance matrix)估计误差。不过这是在假定所有数据点都是绝对精确的情况下才成立。而在实际工作中,测量值不可避免地带有误差,忽略这些误差显然会低估相关系数的误差。那么该如何合理考虑数据点的误差,并绘制相应的置信带(confidence band,表示拟合函数的可能出现范围)呢?这里我们借助Python中的相关函数来看一下。

上图中的数据座标和误差如下:

它们的相关关系可以用numpy模块中的多项式拟合函数 polyfit 来计算。

可以得到拟合直线为 y = 1.10 x – 0.27, 由协方差矩阵得到的参数误差分别为 [0.03,0.11]。但是这个拟合并没有考虑数据点的误差。我们可以采用更灵活的拟合函数——scipy.optimize 模块中的非线性拟合函数 curve_fit 来实现,代码如下:

可以得到拟合直线为 y = 1.09x-0.25,参数误差为[0.12,0.38]。拟合结果稍有不同,参数误差也合理增加。接下来就是根据这个拟合结果来绘制置信带。但置信带并非参数误差的简单叠加。我们可以测试一下,将误差直接与拟合结果叠加看效果如何,代码及结果如下:

可以看到这样得到的置信带并不正确。因为多项式系数之间并非完全独立(cov非对角阵),它们的上下限自然无法同时达到。那么正确的做法是怎样的呢?我们可以重新看一下置信带的含义。它是表示真实函数以特定概率出现的区域。换句话说,1σ误差置信带就意味着真实函数有68%的可能性出现在这个区域。我们可以根据拟合结果模拟出足够多的函数,然后找出其中68%的结果集中的区域。实际操作时,我们统计的是模拟函数给出的模拟数据点的分布。具体代码和结果如下:

这个结果就很像样了。事实上,借助 uncertainties 模块我们可以由协方差矩阵直接得到置信带,代码如下:

可以看到这样直接得到的青色置信带和前一个模拟方法得到的灰色置信带完全一致。对于通常的拟合需求来说,这样的结果已经可以用了。如果x轴位置上也有误差,那么curvefit就不再适用了,需要借助正交距离回归(Orthogonal Distance Regression,ODR)等方法。这里介绍一个更为普适通用的方法——自助法(bootstrap)。

既然每个数据点及其误差都代表一个高斯分布,我可以根据这些分布进行多次模拟采样,得到符合相同分布的多个模拟数据集。通过对这些模拟数据集的直接拟合,可以得到拟合函数的分布情况,进而求出其中位值和68.2%的置信带。具体代码和结果如下:

这样我们得到的拟合结果为 y = 1.10x -0.27 ,与不带误差拟合的结果一致,其误差为 [0.12,0.40],与带误差拟合的结果相当。它的1σ和2σ的置信带都和 uncertainties 模块给出的边界基本吻合。

这里我们只是从数值计算的角度讨论了直线拟合中置信带的画法操作。如果对相关的数学背景和证明感兴趣,可以参考《统计推断》一书。

订阅评论
提醒

0 评论
内联反馈
查看所有评论