16

24GB メモリを搭載した Windows 8 64 ビット システムで Python 2.7 (64 ビット) を実行しています。通常の のフィッティングを行うSklearn.linear_models.Ridgeと、コードは正常に実行されます。

問題:しかし、フィッティングに使用Sklearn.linear_models.RidgeCV(alphas=alphas)すると、フィッティング手順を実行するMemoryError行で以下に示すエラーが発生します。rr.fit(X_train, y_train)

このエラーを防ぐにはどうすればよいですか?

コードスニペット

def fit(X_train, y_train):
    alphas = [1e-3, 1e-2, 1e-1, 1e0, 1e1]

    rr = RidgeCV(alphas=alphas)
    rr.fit(X_train, y_train)

    return rr


rr = fit(X_train, y_train)

エラー

MemoryError                               Traceback (most recent call last)
<ipython-input-41-a433716e7179> in <module>()
      1 # Fit Training set
----> 2 rr = fit(X_train, y_train)

<ipython-input-35-9650bd58e76c> in fit(X_train, y_train)
      3 
      4     rr = RidgeCV(alphas=alphas)
----> 5     rr.fit(X_train, y_train)
      6 
      7     return rr

C:\Python27\lib\site-packages\sklearn\linear_model\ridge.pyc in fit(self, X, y, sample_weight)
    696                                   gcv_mode=self.gcv_mode,
    697                                   store_cv_values=self.store_cv_values)
--> 698             estimator.fit(X, y, sample_weight=sample_weight)
    699             self.alpha_ = estimator.alpha_
    700             if self.store_cv_values:

C:\Python27\lib\site-packages\sklearn\linear_model\ridge.pyc in fit(self, X, y, sample_weight)
    608             raise ValueError('bad gcv_mode "%s"' % gcv_mode)
    609 
--> 610         v, Q, QT_y = _pre_compute(X, y)
    611         n_y = 1 if len(y.shape) == 1 else y.shape[1]
    612         cv_values = np.zeros((n_samples * n_y, len(self.alphas)))

C:\Python27\lib\site-packages\sklearn\linear_model\ridge.pyc in _pre_compute_svd(self, X, y)
    531     def _pre_compute_svd(self, X, y):
    532         if sparse.issparse(X) and hasattr(X, 'toarray'):
--> 533             X = X.toarray()
    534         U, s, _ = np.linalg.svd(X, full_matrices=0)
    535         v = s ** 2

C:\Python27\lib\site-packages\scipy\sparse\compressed.pyc in toarray(self, order, out)
    559     def toarray(self, order=None, out=None):
    560         """See the docstring for `spmatrix.toarray`."""
--> 561         return self.tocoo(copy=False).toarray(order=order, out=out)
    562 
    563     ##############################################################

C:\Python27\lib\site-packages\scipy\sparse\coo.pyc in toarray(self, order, out)
    236     def toarray(self, order=None, out=None):
    237         """See the docstring for `spmatrix.toarray`."""
--> 238         B = self._process_toarray_args(order, out)
    239         fortran = int(B.flags.f_contiguous)
    240         if not fortran and not B.flags.c_contiguous:

C:\Python27\lib\site-packages\scipy\sparse\base.pyc in _process_toarray_args(self, order, out)
    633             return out
    634         else:
--> 635             return np.zeros(self.shape, dtype=self.dtype, order=order)
    636 
    637 

MemoryError: 

コード

print type(X_train)
print X_train.shape

結果

<class 'scipy.sparse.csr.csr_matrix'>
(183576, 101507)
4

2 に答える 2

19

スタック トレースのこの部分を見てください。

    531     def _pre_compute_svd(self, X, y):
    532         if sparse.issparse(X) and hasattr(X, 'toarray'):
--> 533             X = X.toarray()
    534         U, s, _ = np.linalg.svd(X, full_matrices=0)
    535         v = s ** 2

使用しているアルゴリズムは、numpy の線形代数ルーチンに依存して SVD を実行します。しかし、それらはスパース行列を処理できないため、作成者はそれらを通常の非スパース配列に変換するだけです。これを行うために最初に行わなければならないことは、すべてゼロの配列を割り当ててから、疎行列にまばらに格納された値で適切なスポットを埋めることです。簡単そうですが、計算してみましょう。float64 (デフォルトの dtype。何を使用しているのかわからない場合はおそらく使用している) 要素は 8 バイトを使用します。したがって、提供した配列形状に基づいて、ゼロで埋められた新しい配列は次のようになります。

183576 * 101507 * 8 = 149,073,992,256 ~= 150 gigabytes

システムのメモリ マネージャは、おそらくその割り当て要求を一目見て自殺したのでしょう。しかし、それについて何ができますか?

まず第一に、それはかなりばかげた機能の数のように見えます。問題のドメインや機能については何も知りませんが、ここで次元削減を行う必要があるというのが私の直感です。

次に、アルゴリズムの疎行列の誤った処理を修正することができます。ここは窒息しているから、代わりnumpy.linalg.svdに使えるかもしれない。scipy.sparse.linalg.svds問題のアルゴリズムはわかりませんが、スパース行列には適していない可能性があります。適切なスパース線形代数ルーチンを使用しても、データと同様のサイズの非スパース行列が生成される (または内部的に使用される) 場合があります。疎行列表現を使用して非疎データを表すと、元のスペースよりも多くのスペースを使用するだけになるため、このアプローチは機能しない可能性があります。慎重に進んでください。

于 2013-05-03T03:51:45.987 に答える