NumpyがSVDを実行する方法を理解する


13

私は、行列のランクと行列方程式の解の両方を計算するために、さまざまな方法を使用しています。関数linalg.svdに出会いました。これを、Gaussian Eliminationでシステムを解くという私自身の努力と比較すると、より速く、より正確に見えるようです。私はこれがどのように可能かを理解しようとしています。

私の知る限り、linalg.svd関数はQRアルゴリズムを使用して、行列の固有値を計算します。私はこれが数学的にどのように機能するかを知っていますが、Numpyがどのようにそれを迅速かつあまり正確に失うことなく行うのかわかりません。

私の質問:numpy.svd関数はどのように機能し、より具体的には(ガウス消去と比較して)高速かつ正確にどのように処理するのですか?


2
numpyは、実際のSVDにLapackルーチンdgesddを使用します。あなたの本当の質問はおそらく「Lapack dgesddがどのように機能するのか?」です。
タロンミー

本当に興味があれば、LAPACKソースを調べることをお勧めします。

ご意見をお寄せいただきありがとうございます。おtopicび申し上げます。
RobVerheyen

この投稿はStack Overflowのクロス投稿です。通常、クロスポストはStack Exchangeサイトでは推奨されていません。別のサイトに質問を再投稿するための標準プロトコルは、別のサイトに再投稿する前に、元の投稿を閉じる、削除する、または移行することです。(質問を移行すると、自動的に再
投稿

申し訳ありませんが、プロトコルを認識していませんでした。まだ答えが得られるといいのですが。
RobVerheyen

回答:


15

あなたの質問には多くの問題があります。

ガウス消去法(LU分解)を使用して、行列の数値ランクを計算しないでください。 LU分解は、浮動小数点演算のこの目的には信頼できません。代わりに、(例えば、ランク現出QR分解を使用するxGEQPXか、xGEPQYこれらのルーチンは、追跡するのが困難であるものの、Xは、C、D、S、又はZであるLAPACK、中;参照関連する問題にJedBrownの回答を)、またはSVDを使用(特異値分解など、xGESDDまたはxGESVDxが再びC、D、S、又はZです)。SVDは、数値ランクを決定するためのより正確で信頼性の高いアルゴリズムですが、より多くの浮動小数点演算が必要です。

ただし、線形システムを解くには、LU分解(LAPACKの標準実装である部分ピボットを使用)が実際に非常に信頼できます。部分的ピボットによるLU因数分解が不安定な病理学的ケースがいくつかあります(数値線形代数の講義22を参照)詳細については、TrefethenおよびBauによる)。QR因数分解は、線形システムを解くためのより安定した数値アルゴリズムです。これがおそらく、正確な結果が得られる理由です。ただし、正方行列の場合、LU因数分解よりも2倍の浮動小数点演算が必要です(JackPoulsonがそれを修正するかもしれません)。長方形システムの場合、QR分解は、過剰決定された線形システムの最小二乗解を生成するため、より適切な選択です。SVDは線形システムの解決にも使用できますが、QR分解よりも高価になります。

jannebは、numpy.linalg.svdがxGESDDLAPACKのラッパーであることは正しいです。特異値分解は2段階で進行します。最初に、分解されるマトリックスが2重対角形に縮小されます。LAPACKで2重対角形に縮小するために使用されるアルゴリズムは、おそらくローソン-ハンソン-チャンアルゴリズムであり、1点でQR分解を使用します。TrefethenとBauによる数値線形代数の講義31では、このプロセスの概要を説明しています。次に、xGESDD分割統治アルゴリズムを使用して、2値対角行列から特異値と左右の特異ベクトルを計算します。このステップの背景を知るには、Golub and Van LoanによるMatrix Computations、またはJim DemmelによるApplied Numerical Linear Algebraを参照する必要があります。

最後に、特異値と固有値を混同しないでください。これらの2セットの数量は同じではありません。SVDは、行列の特異値を計算します。MATLABを使用したCleve Molerの数値計算は、特異値と固有値の違いの概要を示しています。一般に、特異行列が固有値の絶対値である通常の行列の場合を除き、与えられた行列の特異値とその固有値の間には明らかな関係はありません。


固有値と特異値の間の関係では、「関係なし」がかなり強いと思います。マトリックスの完全なジョーダン分解を知らない限り、関係はかなりあいまいですが、ジョーダン分解についての情報がある場合(または仮定をする意思がある場合)、一方を使用して他方の推定値を取得できます。
ダン

代わりに何を提案しますか?
ジェフオックスベリー

まず第一に、精巧な答えをありがとう。LU分解を使用してマトリックスランクを厳密に決定できないことがわかりました。あなたの答えは、QR因数分解が実際に私の問題を解決するより速い方法であることを暗示しているようです、正しいですか?SVDの使用に明確な利点はありますか?特異値は固有値ではないという事実をよく知っていました。特異値は、マトリックスの固有値に左からの転置を掛けたものとして計算できるという事実に言及していました。はっきりしなかったのが残念です。
RobVerheyen

私が解く行列は実際には特異であると付け加えるかもしれません。実際、マトリックスのランクは、マトリックスのサイズの約半分にすぎません。おそらく、これはいくつかの方法をより好ましいものにしますか?
-RobVerheyen

1
@RobVerheyen:QRはLUよりも遅くなりますが、かなり正確です。SVDはQRよりもさらに遅くなりますが、SVDは数値ランクを決定するための最も信頼できる方法と見なされます(たとえば、MATLABはrank関数でSVDを使用します)。どちらのアプローチを使用する場合にも、少しの裁量が伴います。SVDアプローチでは、数値ランクは指定された(通常は非常に小さい)カットオフを超える特異値の数です。(QRアプローチは似ていますが、特異値をR行列の対角要素に置き換えます。)
ジェフオックスベリー

8

あなたの質問の文言により、私はあなたの行列が正方形であると仮定しています。zgesvdなどのLAPACKのSVDルーチンは、正方行列の場合、基本的に3段階で進行します。

  1. うんAVAAB:=うんAHAVAうんAVABOn3
  2. 実対称三重対角行列の固有値分解を計算するアルゴリズムのバリエーションを使用して、2重対角SVDを計算します。私の知る限り、実対称三重対角EVP(MRRR)の最も有名なアルゴリズムはまだ2重対角SVDに対して安定していませんが、ここで興味深い議論があります。LAPACKは現在、対角SVDに分割統治アプローチを使用しています。二重対角SVDは生成します{うんBVBΣ}B=うんBΣVBHOn2On3
  3. うんABVAH=AA=うんAうんBΣVAVBHうんAVAうんBVBOn3

7

numpy.linalg.svdは、LAPACKの{Z、D} GESDDのラッパーです。LAPACKは、数値線形代数の世界有数の専門家によって非常に慎重に書かれています。実際、この分野に精通していない人がLAPACKを(速度または精度のいずれかで)破ることに成功した場合、それは非常に驚くべきことです。

QRがガウス消去よりも優れている理由については、おそらく/scicomp//に適しています。


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