web-dev-qa-db-ja.com

Scipyでは、curve_fitがパラメーター推定値の共分散をどのように、そしてなぜ計算するか

一部のデータに合わせるためにscipy.optimize.leastsqを使用しています。これらの推定値の信頼区間を取得したいので、cov_x出力を調べますが、これが何であるか、およびこれから私のパラメーターの共分散行列を取得する方法について、ドキュメントは非常に不明確です。

まず、それはヤコビアンであると述べていますが、 notes では、「cov_xはヘッセ行列へのヤコビアン近似」であることも示しているため、実際にはヤコビアンではありません。ヤコビアンからの近似を使用したヘッセ行列。これらのステートメントのどれが正しいですか?

第二に、この文章は私を混乱させます:

パラメータ推定値の共分散を取得するには、この行列に残差分散を乗算する必要があります。curve_fitを参照してください。

私は確かにcurve_fitのソースコードを見て、次のようにしています:

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

これはcov_xs_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

31
HansHarhoff

はい、私は答えを見つけたと思います。最初のソリューション:cov_x * s_sqは、必要なパラメーターの共分散です。対角要素の平方根を取ると、標準偏差が得られます(ただし、共分散に注意してください!)。

残差分散=縮小カイ二乗= s_sq = sum [(f(x)-y)^ 2] /(N-n)。ここで、Nはデータポイントの数、nはフィッティングパラメーターの数です。 簡約カイ二乗

私の混乱の理由は、leastsqによって与えられるcov_xは実際には他の場所ではcov(x)と呼ばれるものではなく、縮小されたcov(x)または分数cov(x)であるためです。他の参考文献に記載されていない理由は、数値計算に役立つ単純な再スケーリングであるが、教科書には関係がないためです。

ヘシアン対ヤコビアンについては、ドキュメントの言葉遣いが不十分です。ヤコビアンは最低でもゼロなので、どちらのケースでも計算されるのはヘッセ行列です。彼らが意味することは、ヘッセ行列を見つけるためにヤコビアンの近似を使用しているということです。

さらなるメモ。 curve_fitの結果は実際にはエラーの絶対サイズを考慮せず、提供されたシグマの相対サイズのみを考慮しているようです。つまり、エラーバーが100万倍変化しても、返されるpcovは変化しません。これはもちろん正しくありませんが、標準的な方法であるようです。 Matlabは、カーブフィッティングツールボックスを使用するときに同じことを行います。正しい手順は次のとおりです: https://en.wikipedia.org/wiki/Linear_least_squares_(mathematics)#Parameter_errors_and_correlation

最適なものが見つかれば、少なくとも線形最小二乗法では、これを行うのはかなり簡単です。

26
HansHarhoff

同様の質問を検索しているときにこの解決策を見つけましたが、HansHarhoffの答えはわずかに改善されています。 leastsqからの完全な出力は、infodict ['fvec'] = f(x) -yを含む)戻り値infodictを提供します。したがって、削減されたカイ二乗= )

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

ところで。これを解決するために大掛かりな作業のほとんどを行ってくれたHansHarhoffに感謝します。

7
Jim Parker