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

2024-05-15 16:02:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在用scipy.optimize.leastsq来拟合一些数据。我想得到这些估计值的一些置信区间,因此我研究了cov_x输出,但是文档对于这是什么以及如何从中获取参数的协方差矩阵非常不清楚。

首先它说它是一个雅可比函数,但是在notes中它也说“cov_x是对Hessian的雅可比近似”,所以它实际上不是一个雅可比函数,而是一个Hessian,使用了一些来自Jacobian的近似。这些陈述中哪一个是正确的?

其次,这句话让我困惑:

This matrix must be multiplied by the residual variance to get the covariance of the parameter estimates – see 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)是我想要的东西。

我如何将曲线拟合所做的事情与我在维基百科上看到的联系起来: http://en.wikipedia.org/wiki/Propagation_of_uncertainty#Non-linear_combinations


Tags: ofthe函数lensqscipycovfit
2条回答

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

残差方差=约化卡方=s嫒sq=和[(f(x)-y)^2]/(N-N),其中N是数据点的个数,N是拟合参数的个数。Reduced chi square

我困惑的原因是,leatsq给出的cov_x实际上并不是其他地方所称的cov(x),而是约化cov(x)或分数cov(x)。它没有出现在其他任何参考文献中的原因是,它是一个简单的重标度,在数值计算中很有用,但与教科书无关。

关于海森和雅各比,文档的措辞很差。在这两种情况下计算的是Hessian,这是显而易见的,因为Jacobian最小为零。他们的意思是,他们使用雅可比的近似值来找到黑森。

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

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

我在寻找类似问题的过程中找到了这个解决方案,而我对汉沙霍夫的答案只有一点改进。leatsq的完整输出提供了一个返回值infodict,它包含infodict['fvec']=f(x)-y。因此,要计算缩减的卡方=(在上面的符号中)

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

顺便说一句,谢谢汉沙霍夫为解决这个问题做了大量的工作。

相关问题 更多 >