共分散行列の平方根を正定にする(Matlab)


9

動機:私は、MATLAB(無香料カルマンフィルター)で状態推定器を書いています。これは、反復ごとに(つまり、共分散行列に対して)共分散行列の(上三角)平方根の更新を要求します。、)であることは事実です。必要な計算を実行するには、MATLAB 関数を使用して、ランク1のコレスキー更新とダウンデートを行う必要があります。P P = S S TSPP=SSTcholupdate

問題:残念ながら、反復の過程で、この行列は正定性を失う場合があります。コレスキーのダウンデートは、非PDマトリックスでは失敗します。S

私の質問は、MATLABで正定にする簡単で信頼できる方法はありますか?S

またはより一般的には、任意の共分散行列を正定にする良い方法はありますか?X


  • Sはフルランクです
  • 私は固有分解アプローチを試しました(これは機能しませんでした)。これは基本的に見つけ、すべての負の要素を設定し、新しいを再構築することを含み、ここでは正の要素のみをもつ行列です。 V D = 1 × 10 8 S = V D V T V D S=VDVTV,D=1×108S=VDVTV,D
  • Highamアプローチ(Rとしてとして実装されていますnearpd)は知っていますが、最も近いPSD行列にのみ投影されるようです。コレスキー更新にPDマトリックスが必要です。

S=PPSP

S

私も同じ問題を抱えています。私はsqrtm(x)関数を試しましたが、それは数回の反復でしか機能しませんでした。解決策は見つかりましたか?

S+kkS

少し遅いですが、ピボットは数値的に不安定な場合に役立つ戦略です。
確率論的14

回答:


4

これは私が過去に使用したコードです(SVDアプローチを使用)。すでにお試しになったとおっしゃっていましたが、いつもうまくいきましたので、参考になるかどうか投稿してみようと思いました。

function [sigma] = validateCovMatrix(sig)

% [sigma] = validateCovMatrix(sig)
%
% -- INPUT --
% sig:      sample covariance matrix
%
% -- OUTPUT --
% sigma:    positive-definite covariance matrix
%

EPS = 10^-6;
ZERO = 10^-10;

sigma = sig;
[r err] = cholcov(sigma, 0);

if (err ~= 0)
    % the covariance matrix is not positive definite!
    [v d] = eig(sigma);

    % set any of the eigenvalues that are <= 0 to some small positive value
    for n = 1:size(d,1)
        if (d(n, n) <= ZERO)
            d(n, n) = EPS;
        end
    end
    % recompose the covariance matrix, now it should be positive definite.
    sigma = v*d*v';

    [r err] = cholcov(sigma, 0);
    if (err ~= 0)
        disp('ERROR!');
    end
end

あなたの努力をありがとう-残念ながら、それはうまくいきませんでした。(私は3行のプログラムで非常によく似たことをしていました:)[V,D] = eig(A); D(D <= 1e-10) = 1e-6; Apd = V*A*V';。このアプローチはRebonatoとJackelによるアプローチに似ており、私のような病理学的ケースでは失敗するようです。
ギリアド

それは残念だ。投稿する時間があれば、これ(および他の方法)が失敗する原因となったマトリックスの例に興味があります。これは、実行し続けるのに非常に深刻な問題です。解決策が見つかれば幸いです。
Nick

2

Matlabで:

help cholupdate

私は得る

CHOLUPDATE Rank 1 update to Cholesky factorization.
    If R = CHOL(A) is the original Cholesky factorization of A, then
    R1 = CHOLUPDATE(R,X) returns the upper triangular Cholesky factor of A + X*X',
    where X is a column vector of appropriate length.  CHOLUPDATE uses only the
    diagonal and upper triangle of R.  The lower triangle of R is ignored.

    R1 = CHOLUPDATE(R,X,'+') is the same as R1 = CHOLUPDATE(R,X).

    R1 = CHOLUPDATE(R,X,'-') returns the Cholesky factor of A - X*X'.  An error
    message reports when R is not a valid Cholesky factor or when the downdated
    matrix is not positive definite and so does not have a Cholesky factorization.

    [R1,p] = CHOLUPDATE(R,X,'-') will not return an error message.  If p is 0
    then R1 is the Cholesky factor of A - X*X'.  If p is greater than 0, then
    R1 is the Cholesky factor of the original A.  If p is 1 then CHOLUPDATE failed
    because the downdated matrix is not positive definite.  If p is 2, CHOLUPDATE
    failed because the upper triangle of R was not a valid Cholesky factor.

    CHOLUPDATE works only for full matrices.

    See also chol.

私は使用してcholupdateいますが、私の質問はR(この場合は)明確にすることです。私Rが非pdで、cholupdate(R,X,'-')(ダウンデート)が失敗する場合があります。
ギレアデ

1
この形式のすべてのオンラインアルゴリズム(更新とダウンデート)では、このような精度の問題が発生します。1dでも同様の問題があり、分散の負の推定値になりました。私の提案は、観測された最後のkベクトルの循環バッファーを保持し、cholupdate失敗した場合は、その循環バッファーに基づいて共分散を再計算してコストを食うことです。メモリがあり、これが発生したときに時折ヒットする時間に耐えることができる場合、精度と実装の容易さの点でより良い方法を見つけることができません。
shabbychef '19年

ありがとう、それは考えるべきことです。残念ながら、私の共分散行列は非常に多くの変換を経ているため、どの時点で循環バッファーからの再計算が必要かは明確ではありません。それでも、他のすべてが失敗した場合は、最後の既知のPD共分散行列を使用できるはずです。これにより、私の推定値にバイアスが生じないことを期待しています。
Gilead

2

コレスキー分解を計算する1つの代替方法は、Sの対角要素を1に固定してから、正の要素を持つ対角行列Dを導入することです。

これにより、計算時に平方根を取る必要がなくなり、「小さな」数値(つまり、浮動小数点演算によって発生する丸めが問題となるほど小さい数値)を処理するときに問題が発生する可能性があります。ウィキペディアのページには、この調整アルゴリズムのルックスが好きなものがあります。

P=SSTP=RDRTS=RD12

お役に立てれば!


1
おかげで、それは私が潜在的に使用できるテクニックです。それはここに実装されているようです:infohost.nmt.edu/~borchers/ldlt.html
Gilead

1

マトリックスが「本当に」正定でない場合、コレスキー分解は事実上失敗する可能性があります。2つのケースが表示されるか、負の値を持っているか、最小の値が正であるがゼロに近い。2番目のケースは理論的には解決策を与える必要がありますが、数値的には困難です。直感的な場合は、問題を解決するために、行列の対角に小さな定数を追加します。しかし、この方法はソリューションをわずかに変更するため、厳密ではありません。非常に高い精度のソリューションを計算する必要がある場合は、修正コレスキー分解についていくつかの研究を試してください。


0

Pが正定でないと推定しようとする場合、問題を求めてアルゴリズムを追跡することになるので、この状況は回避する必要があります。問題が数値の場合:Pは正定ですが、数値の固有値は小さすぎます-状態に新しい呼び出しを試みてください問題が本当に非正定の場合-別の状態変数のセットを試してください。アドバイスが遅すぎないことを願っていますよろしく、Zeev

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.