Python MemoryError, wenn dabei die Montage mit Scikit-learn
Ich verwende Python 2.7 (64-bit) auf eine Windows 8 64-bit-system mit 24GB Speicher. Bei der Montage der üblichen Sklearn.linear_models.Ridge
, der code läuft einwandfrei.
Problem: Allerdings, wenn Sie Sklearn.linear_models.RidgeCV(alphas=alphas)
für den Einbau, ich Lauf in den MemoryError
Fehler unten auf der Linie rr.fit(X_train, y_train)
führt, dass die fitting-Prozedur.
Wie kann ich verhindern, dass dieser Fehler?
Code-snippet
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)
Fehler
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:
Code
print type(X_train)
print X_train.shape
Ergebnis
<class 'scipy.sparse.csr.csr_matrix'>
(183576, 101507)
- Was ist die Größe (Form und dtype) Ihres Datenbestandes
X_train
? - Form
(183576, 101507)
,type
vonX_train
ist<class 'scipy.sparse.csr.csr_matrix'>
. Wie finde ich die "dtype"?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werfen Sie einen Blick auf diesen Teil des stack trace:
Den Algorithmus, die Sie verwenden basiert auf numpy lineare algebra-Routinen zu tun, SVD. Aber diese können nicht mit sparse-Matrizen, so dass der Autor einfach wandelt Sie in normalen nicht-sparse-arrays. Die erste Sache, die geschehen muss, für das reservieren ist ein all-null-array und füllen Sie dann die entsprechenden stellen mit den Werten spärlich gespeichert in der sparse-matrix. Klingt einfach genug, aber lassen Sie uns Mathe. Ein float64 (die default dtype, die Sie wahrscheinlich verwenden, wenn Sie nicht wissen, was Sie verwenden) element 8 bytes. So, basierend auf den array-Form, die Sie haben, die neue zero-array gefüllt werden:
Ihrem system Speicher-manager wahrscheinlich warf einen Blick auf, dass die Zuweisung verlangen und Selbstmord begangen. Aber was kann man dagegen tun?
First off, das sieht aus wie eine ziemlich lächerliche Anzahl von Funktionen. Ich weiß nicht, etwas über Ihre problem-domain-oder was Ihre Funktionen sind, aber mein Bauchgefühl ist, dass Sie brauchen, um einige der dimensionsreduktion hier.
Zweite, die Sie versuchen können, zu beheben, der Algorithmus ist falsche Handhabung von sparse-Matrizen. Es erstickt an
numpy.linalg.svd
hier, so dass Sie möglicherweise in der Lage sein zu verwendenscipy.spärlich.linalg.svds
statt. Ich weiß nicht, den Algorithmus in Frage, aber könnte es nicht sein, zugänglich, um sparse Matrizen. Sogar, wenn Sie die entsprechenden sparse linear algebra Routinen, die es haben könnte (oder intern verwenden) einige nicht-sparse-Matrizen mit ähnlichen Formaten wie Ihre Daten. Mit Hilfe einer sparse-matrix-Darstellung zu repräsentieren, nicht-sparse-data führt nur über mehr Platz, als hätten Sie ursprünglich so, dass dieser Ansatz möglicherweise nicht. Gehen Sie mit Vorsicht.Die entsprechende option hier ist gcv_mode. Es kann 3 Werte: "auto", "svd" und "eigen". Standardmäßig ist es auf "auto" eingestellt, die das folgende Verhalten: die Verwendung der svd-Modus, wenn n_samples > n_features, ansonsten verwenden Sie die eigen-Modus.
Da in Ihrem Fall n_samples > n_features, die svd-Modus gewählt wird. Doch die svd-Modus derzeit noch nicht mit dünnbesetzten richtig. scikit-learn, die behoben werden sollte um die ordnungsgemäße Verwendung von sparse-SVD statt der dichten SVD.
Als workaround würde ich die Kraft der eigen-Modus von gcv_mode="eigen", da dieser Modus sollte einwandfrei verarbeitet spärliche Daten. Allerdings n_samples ist sehr groß in deinem Fall. Da die eigen-Modus baut ein kernel-matrix (und damit hat n_samples ** 2 Speicher-Komplexität), die kernel-matrix nicht in den Speicher passt. In diesem Fall würde ich Sie einfach reduzieren Sie die Anzahl der Proben (die eigen-Modus verarbeiten kann sehr große Anzahl von Funktionen ohne problem, obwohl).
In jedem Fall, da beide n_samples und n_features sind Recht groß, Sie drängen diese Umsetzung an seine Grenzen (sogar mit einem richtigen spärlich SVD).
Siehe auch https://github.com/scikit-learn/scikit-learn/issues/1921