2015-11-09 8 views
6

私は巨大な疎行列にPCAを適用しようとしていますが、sklearnのランダム化されたPCAはscipyの疎フォーマットの疎行列を扱うことができます。 Apply PCA on very large sparse matrixsklearnを使用して大スパース行列でPCAを実行する

ただし、私はいつもエラーが発生します。誰かが私が間違っていることを指摘できますか?

入力行列「X_trainは」のfloat64に数字が含まれています

>>>type(X_train) 
<class 'scipy.sparse.csr.csr_matrix'> 
>>>X_train.shape 
(2365436, 1617899) 
>>>X_train.ndim 
2 
>>>X_train[0]  
<1x1617899 sparse matrix of type '<type 'numpy.float64'>' 
    with 81 stored elements in Compressed Sparse Row format> 

私がやろうとしています:

>>>from sklearn.decomposition import RandomizedPCA 
>>>pca = RandomizedPCA() 
>>>pca.fit(X_train) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/decomposition/pca.py", line 567, in fit 
    self._fit(check_array(X)) 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/utils/validation.py", line 334, in check_array 
    copy, force_all_finite) 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sklearn/utils/validation.py", line 239, in _ensure_sparse_format 
    raise TypeError('A sparse matrix was passed, but dense ' 
TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array. 

私は密行列に変換しようとした場合、私はメモリ不足だと思います。

>>> pca.fit(X_train.toarray()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/compressed.py", line 949, in toarray 
    return self.tocoo(copy=False).toarray(order=order, out=out) 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/coo.py", line 274, in toarray 
    B = self._process_toarray_args(order, out) 
    File "/home/RT11/.pyenv/versions/2.7.9/lib/python2.7/site-packages/scipy/sparse/base.py", line 800, in _process_toarray_args 
    return np.zeros(self.shape, dtype=self.dtype, order=order) 
MemoryError 
+0

リンクした質問にこの回答がありますか? http://stackoverflow.com/a/10721425/2272172 – cel

+0

はい、私は、巨大な疎な行列にPCAを適用する方法があるかどうかを知りたいと思います(できるだけPythonとSklearnを使用して) – khassan

+0

あなたはすでに 'TruncatedSVD'を使用していますそれは動作しませんでしたか?もしそうなら、それもあなたの質問に書いてください。 – cel

答えて

6

PCAの性質上、入力がスパース行列であっても、出力は出力されません。あなたは簡単な例でそれを確認することができます。

>>> from sklearn.decomposition import TruncatedSVD 
>>> from scipy import sparse as sp 

非ゼロとしてそのデータの0.01%とランダムスパース行列を作成します。

>>> X = sp.rand(1000, 1000, density=0.0001) 

それにPCAを適用します。

>>> clf = TruncatedSVD(100) 
>>> Xpca = clf.fit_transform(X) 

、結果を確認します

>>> type(X) 
scipy.sparse.coo.coo_matrix 
>>> type(Xpca) 
numpy.ndarray 
>>> print np.count_nonzero(Xpca), Xpca.size 
95000, 100000 

エントリの95000が非ゼロであることを示唆している、しかし、

>>> np.isclose(Xpca, 0, atol=1e-15).sum(), Xpca.size 
99481, 100000 

99481要素は、0<1e-15)に近いですが、ではなく、0です。

つまり、PCAの場合、入力が疎行列であっても、出力は出力されません。したがって、行列から100,000,000(1e8)の成分を抽出しようとすると、1e8 x n_features(例では1e8 x 1617899)の密行列になります。もちろん、これはメモリに保持することはできません。

私は熟練した統計者ではありませんが、scikit-learnの実装の問題ではないので、現在のところscikit-learnを使用してこれに関する作業警告はありませんと、私はSparse PCAの数学的定義疎なSVD)を使用して、結果を密にします。

唯一の回避策は、少量のコンポーネントから開始して、メモリに保持できるデータと説明されたデータの割合をバランスさせるまで増加させることです(あなたは以下のように計算できます):

>>> clf.explained_variance_ratio_.sum() 
+0

私は1.6Mから500までの機能の数を減らすことができました。あなたは非常に大きなRAMを持っていない限り、巨大な行列の上にSVDを実行することは不可能であるように見えます。 – khassan

関連する問題