Using a sparse matrix versus numpy array

7月 20, 2021
admin

The scipy sparse matrix package, and similar ones in MATLAB, was based on ideas developed from linear algebra problems, such as solving large sparse linear equations (ex.finite difference and finite element implementations). そのため、行列積 (numpy 配列の dot 積) や方程式ソルバーといったものがよく開発されています。

私のおおよその経験では、疎な csr 行列積が、同等の密な dot 操作よりも速くなるには 1%の疎性を持つ必要があります – 言い換えれば、99 のゼロに対して非ゼロをひとつという意味です。 (ただし、以下のテストを参照)

しかし、人々はメモリを節約するために疎な行列を使用しようとします。 しかし、そのような行列は値の 3 つの配列を保存しなければならないことに注意してください (少なくとも coo フォーマットでは)。 つまり,メモリを節約するためには,スパース性が1/3以下でなければならないのです. 5086>

scipy パッケージは多くのスパースフォーマットを実装しています。 coo フォーマットが最も理解しやすく、構築しやすいものです。 ドキュメントに従って構築し、.data, .row, .col 属性 (3 つの 1 次元配列) を見てください。

csrcsc は通常 coo 形式から構築され、データを少し圧縮しているので少し理解しにくいものになっています。 5086>

csr フォーマットのインデックスを作成することも可能ですが、一般にこれは同等の密な行列/配列の場合よりも遅くなります。 値の変更 (特に 0 から非ゼロへ) や連結、インクリメンタルな増加といった他の操作も遅くなります。

lil (リストのリスト) も理解しやすく、インクリメンタルに構築するには最良です。 dok は実際には辞書のサブクラスです。

重要な点は、疎行列は 2 次元に限定され、多くの点で np.matrix クラスのように動作する (サブクラスではありませんが) ことです。

これらの行列を使うことの利点/欠点を見つけるには、scikit-learnsparse を使った他の質問を検索することが最もよい方法かもしれません。 何度も回答していますが、「学習」側より「疎」側の方がよくわかります。 便利だとは思うのですが、フィット感が必ずしもベストではないというのが実感です。 カスタマイズはlearn側で。 今のところ sparse パッケージはこの用途に最適化されていません。

指定したスパース性を持つスパース行列を作成するために sparse.random メソッドを使用して、いくつかの行列積テストを試したところ、sparse.random メソッドを使用することがわかりました。 スパース行列の乗算は、私が予想していたよりも良いパフォーマンスを示しました。

In : M=sparse.random(1000,1000,.5)In : timeit M1=M*M1 loops, best of 3: 2.78 s per loopIn : timeit Ma=M.toarray(); M2=Ma.dot(Ma)1 loops, best of 3: 4.28 s per loop

これはサイズの問題です。小さい行列では密な dot が高速です

In : M=sparse.random(100,100,.5)In : timeit M1=M*M100 loops, best of 3: 3.24 ms per loopIn : timeit Ma=M.toarray(); M2=Ma.dot(Ma)1000 loops, best of 3: 1.44 ms per loop

ただし、インデックス作成を比較してください

In : timeit M.tocsr()10 loops, best of 3: 86.4 ms per loopIn : timeit Ma1000000 loops, best of 3: 318 ns per loopIn : timeit Ma=M.toarray();Ma10 loops, best of 3: 23.6 ms per loop

コメントを残す

メールアドレスが公開されることはありません。