web-dev-qa-db-ja.com

scipyを使用して行列ランクを計算する

Scipyを使用してマトリックスの 数学的ランク を計算したいと思います。最も明白な関数numpy.rankは、配列の次元を計算します(つまり、スカラーの次元は0、ベクトル1、行列2などです)。 numpy.linalg.lstsqモジュールにこの機能があることは知っていますが、そのような基本的な操作がマトリックスクラスのどこかに組み込まれているのではないかと思っていました。

ここに明示的な例があります:

from numpy import matrix, rank
A = matrix([[1,3,7],[2,8,3],[7,8,1]])
print rank(A)

これにより、2にディメンションが与えられ、ここで3の答えを探しています。

41
Hooked

Numpyはnumpy.linalg.matrix_rank()を提供します:

>>> import numpy
>>> numpy.__version__
'1.5.1'
>>> A = numpy.matrix([[1,3,7],[2,8,3],[7,8,1]])
>>> numpy.linalg.matrix_rank(A)
3
57
Simon

実際にこれを実行する必要がある人々に大まかなコードスニペットを提供するため。自由に改善してください。

u, s, v = np.linalg.svd(A)
rank = np.sum(s > 1e-10)
14

numpyがランク付け機能を提供していない場合は、独自に記述してみませんか?

ランクを計算する効率的な方法は、特異値分解によるものです。行列のランクは、非ゼロの特異値の数と等しくなります。

def rank(A, eps=1e-12):
    u, s, vh = numpy.linalg.svd(A)
    return len([x for x in s if abs(x) > eps])

epsはアプリケーションによって異なります。ほとんどの場合、1e-12がゼロに対応することに同意しますが、eps = 1e-9の場合でも数値の不安定性を目にする可能性があります。

あなたの例を使用すると、答えは3つです。 2番目の行を[2, 6, 14](行1に線形従属)に変更すると、答えは2になります(「ゼロ」の固有値は4.9960E-16です)

5
Escualo

この回答は古くなっています。

答えは「いいえ」です。現在、scipyで配列/行列の行列ランクを計算するための専用の関数はありません。 1つを追加することは以前に議論されましたが、それが起こるとしたら、それはまだ信じられていません。

2
Mike Graham

scipyには、ランダムな方法を使用して行列/ LinearOperatorのランクを推定するための効率的な 内挿法 が含まれるようになりました。

>>> from numpy import matrix
>>> A = matrix([[1,3,7],[2,8,3],[7,8,1]], dtype=float)  # doesn't accept int

>>> import scipy.linalg.interpolative as sli
>>> sli.estimate_rank(A, eps=1e-10)
3
1
jawknee

特にNumpyについては知りませんが、それがマトリックスの組み込み演算になる可能性は低いです。これには、かなり集中的な数値計算(および浮動小数点の丸め誤差などに関連する問題)と特定のコンテキストで適切な場合と適切でない場合があるしきい値の選択が含まれます。アルゴリズムの選択は、正確かつ迅速に計算するために重要です。

基本クラスに組み込まれているものは、最も複雑な行列乗算など、独自の簡単な方法で実行できるものである傾向があります。

1
Brooks Moses

線形代数関数は一般にnumpy.linalgにグループ化されます。 (より多くの機能を持つscipy.linalgからも利用できます。)これにより、ポリモーフィズムが可能になります。関数は、SciPyが処理する任意のタイプを受け入れることができます。

だから、はい、the numpy.linalg.lstsq functionはあなたが求めていることを行います。なぜそれが不十分なのですか?

1
bignose