在Scipy中,curve_fit如何以及为什么计算参数估计的协方差

时间:2013-02-13 13:08:43

标签: python scipy curve

我一直在使用scipy.optimize.leastsq来填充一些数据。我想在这些估计值上得到一些置信区间,所以我查看了cov_x输出,但文档很清楚这是什么以及如何从中得到参数的协方差矩阵。

首先,它说它是一个雅可比人,但在notes中它也说“cov_x是对哈西安的雅可比近似”,因此它实际上不是雅可比人而是Hessian使用Jacobian的近似值。哪些陈述是正确的?

其次这句话让我感到困惑:

  

此矩阵必须乘以残差方差才能得到参数估计的协方差 - 请参阅curve_fit

我确实去查看curve_fit的源代码:

s_sq = (func(popt, *args)**2).sum()/(len(ydata)-len(p0))
pcov = pcov * s_sq

对应于将cov_x乘以s_sq,但我无法在任何参考文献中找到此等式。有人能解释为什么这个等式是正确的吗? 我的直觉告诉我它应该是另一种方式,因为cov_x应该是一个衍生物(雅可比或黑森),所以我在思考: cov_x * covariance(parameters) = sum of errors(residuals)其中sigma(parameters)是我想要的东西。

如何连接物体curve_fit与我所看到的一样。维基百科: http://en.wikipedia.org/wiki/Propagation_of_uncertainty#Non-linear_combinations

3 个答案:

答案 0 :(得分:26)

好的,我想我找到了答案。首先是解决方案: cov_x * s_sq只是你想要的参数的协方差。采用对角元素的sqrt将给出标准差(但要小心协方差!)。

残差方差=减小的chi square = s_sq = sum [(f(x)-y)^ 2] /(N-n),其中N是数据点的数量,n是拟合参数的数量。 Reduced chi square

我混淆的原因是,由lesssq给出的cov_x实际上并不是其他地方所谓的cov(x),而是减少的cov(x)或小数cov(x)。它没有出现在任何其他参考文献中的原因是它是一个简单的重新缩放,在数值计算中很有用,但与教科书无关。

关于Hessian与Jacobian,文档措辞不佳。在两种情况下计算的Hessian都是显而易见的,因为Jacobian至少为零。他们的意思是他们使用Jacobian的近似来找到Hessian。

进一步说明。似乎curve_fit结果实际上并不考虑错误的绝对大小,而只考虑所提供的sigma的相对大小。这意味着即使错误栏改变了一百万倍,返回的pcov也不会改变。这当然不对,但似乎是标准做法,即。使用曲线拟合工具箱时,Matlab也会做同样的事情。此处描述了正确的过程:https://en.wikipedia.org/wiki/Linear_least_squares_(mathematics)#Parameter_errors_and_correlation

一旦找到最佳值,这似乎相当简单,至少对于线性最小二乘法来说。

答案 1 :(得分:7)

我在寻找类似问题时找到了这个解决方案,而HansHarhoff的答案我只有一点点改进。来自leastsq的完整输出提供了一个返回值infodict,其中包含infodict ['fvec'] = f(x)-y。因此,计算减小的卡方=(在上面的表示法中)

s_sq = (infodict['fvec']**2).sum()/ (N-n)

顺便说一句。感谢HansHarhoff为解决这个问题做了大部分繁重的工作。

答案 2 :(得分:1)

数学

首先,我们从线性回归开始。在许多统计问题中,我们假设变量具有一些具有未知参数的基本分布,并且我们估计了这些参数。在线性回归中,我们假设因变量y i 与自变量x ij 具有线性关系:

y i = x i1 β 1 + ... + x ip β p +σε i ,i = 1,...,n。

其中ε i 具有独立的标准正态分布,β j 是p个未知参数,σ也未知。我们可以将其写成矩阵形式:

Y = Xβ+σε,

其中Y,β和ε是列向量。为了找到最佳的β,我们最小化平方和

S =(Y-Xβ) T (Y-Xβ)。

我只是写出解决方案,

β^ =(X T X) -1 X T Y。

如果我们将Y作为特定的观测数据,则β^是该观测下β的估计。另一方面,如果我们将Y视为随机变量,则估计量β^也将变为随机变量。这样,我们可以看到β^的协方差。

因为Y具有多元正态分布,而β^是Y的线性变换,所以β^也具有多元正态分布。 β^的协方差矩阵为

Cov(β^)=(X T X) -1 X T Cov(Y)((X T X) -1 X T T =(X T X)- 1 σ 2

但是在这里σ是未知的,因此我们也需要估计它。如果我们让

Q =(Y-Xβ^) T (Y-Xβ^),

可以证明Q /σ 2 具有卡方分布,自由度为n-p(此外,Q与β^无关)。这使得

σ^ 2 = Q /(n-p)

σ 2 的无偏估计量。因此,Cov(β^)的最终估计是

(X T X) -1 Q /(n-p)。

SciPy API

curve_fit最方便,第二个返回值pcov只是β^协方差的估计,即最终结果(X T X)上面 -1 Q /(n-p)。

leastsq中,第二个返回值cov_x为(X T X) -1 。从S的表达式中,我们看到X T X是S的Hessian(准确地说是Hessian的一半),这就是为什么文档说cov_x是Hessian的逆。要获得协方差,您需要将cov_x乘以Q /(n-p)。

非线性回归

在非线性回归中,y i 非线性地取决于参数:

y i = f( x i ,β 1 ,...,β p )+σε i

我们可以计算f关于β j 的偏导数,因此它变得近似线性。然后,该计算基本上与线性回归相同,只是我们需要迭代地逼近最小值。实际上,该算法可以是更复杂的算法,例如Levenberg-Marquardt算法,它是默认的curve_fit

有关提供Sigma的更多信息

本节介绍sigma中的absolute_sigmacurve_fit参数。对于curve_fit的基本用法,当您不了解Y的协方差时,可以忽略此部分。

绝对西格玛

在上面的线性回归中,y i 的方差为σ且未知。如果您知道方差。您可以通过curve_fit参数将其提供给sigma并设置absolute_sigma=True

假设您提供的sigma矩阵为Σ。即

Y〜N(Xβ,Σ)。

Y具有均值Xβ和协方差Σ的多元正态分布。我们希望最大化Y的可能性。根据Y的概率密度函数,这等于最小化

S =(Y-Xβ) T Σ -1 (Y-Xβ)。

解决方案是

β^ =(X T Σ -1 X) -1 X T Σ -1 是。

Cov(β^)=(X T Σ -1 X) -1

上面的β^和Cov(β^)是curve_fitabsolute_sigma=True的返回值。

相对西格玛

在某些情况下,您不知道y i 的确切方差,但是您知道不同y i 之间的相对关系,例如y的方差 2 是y 1 的方差的4倍。然后,您可以传递sigma并设置absolute_sigma=False

这次

Y〜N(Xβ,Σσ)

具有已知矩阵Σ和未知数σ。最小化的目标函数与绝对sigma相同,因为σ为常数,因此估计量β^相同。但是协方差

Cov(β^)=(X T Σ -1 X) -1 σ 2

中有未知的σ。要估算σ,

Q =(Y-Xβ^) T Σ -1 (Y-Xβ^)。

同样,Q /σ 2 具有卡方分布,自由度为n-p。

Cov(β^)的估计是

(X T Σ -1 X) -1 Q /(n-p)。

这是curve_fitabsolute_sigma=False的第二个返回值。