私は、単一の(トレーニング)ベクトルと多数の他の(観測)ベクトルの間でJensen-Shannon divergenceを計算するために、NumPy/Scipyに関数を実装しようとしています。観測ベクトルは非常に大きい(500,000x65536)Scipy sparse matrixに格納されます(密行列はメモリに収まらない)。numpy/scipyで非常に反復的な行列を疎な行列に追加していますか?
I Tが訓練ベクトルであり、各観測ベクトルO I、のためにT + O Iを計算するために必要なアルゴリズムの一部として。私はNumPyの通常の放送規則を使ってこれを行う方法を見つけることができませんでした。なぜなら、疎な行列はそれらをサポートしていないように思われるからです(Tが密な配列として残っていると、Scipyは、私がTを疎な行列にすると、T + O iは形が矛盾するので失敗します)。 〜
training = sp.csr_matrix(training.astype(np.float32))
tindptr = np.arange(0, len(training.indices)*observations.shape[0]+1, len(training.indices), dtype=np.int32)
tindices = np.tile(training.indices, observations.shape[0])
tdata = np.tile(training.data, observations.shape[0])
mtraining = sp.csr_matrix((tdata, tindices, tindptr), shape=observations.shape)
しかし、それは唯一の保存だとき、これは、(6ギガバイトの周りに)メモリの膨大な量を占める:
は現在、私は500,000x65536スパース行列に訓練ベクトルをタイリングする著しく非効率的なステップを取っています1500の「本当の」要素。それはまた、構築がかなり遅いです。stride_tricksを使用して、CSRマトリクスのindptrとデータメンバーが繰り返しデータに余分なメモリを使用しないようにするために、賢明にしようとしました。
training = sp.csr_matrix(training)
mtraining = sp.csr_matrix(observations.shape,dtype=np.int32)
tdata = training.data
vdata = np.lib.stride_tricks.as_strided(tdata, (mtraining.shape[0], tdata.size), (0, tdata.itemsize))
indices = training.indices
vindices = np.lib.stride_tricks.as_strided(indices, (mtraining.shape[0], indices.size), (0, indices.itemsize))
mtraining.indptr = np.arange(0, len(indices)*mtraining.shape[0]+1, len(indices), dtype=np.int32)
mtraining.data = vdata
mtraining.indices = vindices
しかし、ストライドビューmtraining.dataとmtraining.indicesが間違った形をしている(とthis answerに応じて右の形状にする方法はありません)ので、これは動作しません。 .flatイテレータを使用してフラットに見せようとすると、配列のように見えないため(dtypeメンバを持たないなど)、flatten()メソッドを使用するとコピーが終了します。
これを行う方法はありますか?
非常に、非常に遅いです、あなたは、とにかくストレージの6ギガバイトを必要としていますそれを遅らせることで本当に勝てるものはありません。 '+ ='で集計を行うようにしてください!ところで、タイル張りの実装は非常にスマートで効率的ですが、私はあなたがそれより優れているとは思っていません。 'as_strided'で再構成されたベクトルのビューに' csr_matrix'を500000行あなたのアプローチよりもはるかに時間がかかりました。私は内部的に配列がコピーされていると思って、魔法を破っています。あなたの2番目のアプローチは、あなたが指摘しているように、numpyで行うことはできません。 – Jaime
残念ながら、CSRマトリクスをインプレースで変更することはできません(+ = NotImplementedが発生します)。だから私は私が(理論的に)必要とする3倍のメモリを使用することに悩まされていると思います。私が(寛大な)32GBの限界に近づくにつれて苦しいです。 –