2012-06-25 6 views
7

J'essaie d'utiliser l'objet LogisticRegression de sklearn 0.11 pour ajuster un modèle sur 200 000 observations avec environ 80 000 fonctionnalités. L'objectif est de classer les descriptions de texte court dans 1 des 800 classes.Erreur de mémoire de régression logistique de Scikit-Learn

Lorsque je tente d'adapter le classificateur pythonw.exe me donne:

Erreur d'application "L'instruction à ... mémoire à 0x00000000". La mémoire n'a pas pu être écrite. "

Les caractéristiques sont extrêmement clairsemées, environ 10 par observation, et sont binaires (1 ou 0), donc par mon dos du calcul de l'enveloppe mes 4 Go de RAM devraient être en mesure de gérer les exigences de mémoire, mais cela ne semble pas être le cas.Les modèles ne correspondent que lorsque j'utilise moins d'observations et/ou moins de fonctionnalités

Si quoi que ce soit, je voudrais utiliser encore plus d'observations et de fonctionnalités. La compréhension naïve est que la bibliothèque liblinear qui exécute les choses dans les coulisses est capable de supporter cela.)

Mon code ressemble à ceci:

y_vectorizer = LabelVectorizer(y) # my custom vectorizer for labels 
y = y_vectorizer.fit_transform(y) 

x_vectorizer = CountVectorizer(binary = True, analyzer = features) 
x = x_vectorizer.fit_transform(x) 

clf = LogisticRegression() 
clf.fit(x, y) 

Les caractéristiques function() Je passe à l'analyseur renvoie simplement une liste de chaînes indiquant les caractéristiques détectées à chaque observation. J'utilise Python 2.7, sklearn 0.11, Windows XP avec 4 Go de mémoire vive (RAM).

+0

L'interpréteur Python s'est-il bloqué? Ecrire à '0x0' est une erreur assez grave, nous (les développeurs de scikit-learn) devrions l'examiner. –

+0

L'interpréteur Python se bloque. –

+0

L'ensemble de données que vous utilisez est-il public? Pouvez-vous reproduire ce crash avec un ensemble de données plus petit (par exemple avec 'x_first_half = x [: x.shape [0]/2]' ou 'x_second_half = x [x.forme [0]/2:] '? – ogrisel

Répondre

20

liblinear (la mise en oeuvre du support de sklearn.linear_model.LogisticRegression) tiendra sa propre copie des données, car il est une bibliothèque C++ dont la mise en page de mémoire interne ne peut pas être directement projetée sur une matrice creuse pré-alloué en scipy comme scipy.sparse.csr_matrix ou scipy.sparse.csc_matrix.

Dans votre cas, je vous recommande de charger vos données en tant que scipy.sparse.csr_matrix et alimenter un sklearn.linear_model.SGDClassifier (avec loss='log' si vous voulez un modèle de régression logistique et la possibilité d'appeler la méthode predict_proba). ne copie pas les données d'entrée s'il utilise déjà la disposition de mémoire scipy.sparse.csr_matrix.

Attendez-vous à allouer un modèle dense de 800 * (80000 + 1) * 8/(1024 ** 2) = 488 Mo en mémoire (en plus de la taille de votre jeu de données en entrée).

Edit: comment optimiser l'accès mémoire pour votre ensemble de données

Pour mémoire libre après extraction du jeu de données, vous pouvez:

x_vectorizer = CountVectorizer(binary = True, analyzer = features) 
x = x_vectorizer.fit_transform(x) 
from sklearn.externals import joblib 
joblib.dump(x.tocsr(), 'dataset.joblib') 

puis quittez ce processus de python (pour forcer désallocation mémoire complète) et dans un nouveau processus:

x_csr = joblib.load('dataset.joblib') 

Sous linux/OSX, vous pouvez mapper la mémoire encore plus efficacement avec:

x_csr = joblib.load('dataset.joblib', mmap_mode='c') 
+3

Excellente réponse, vous fournissez un meilleur support pour ce logiciel libre que d'autres donnent pour un logiciel très cher, le monde vous doit beaucoup de mercis. Une note mineure cependant, la méthode predict_proba de SGDClassifier semble seulement être implémentée pour les tâches de classification de 2 catégories. –

+0

En effet, j'ai oublié à ce sujet. Il y a actuellement une discussion sur la liste de diffusion pour ajouter une régression logistique multinomiale correcte à SGDClassifier ou pour implémenter la mise à l'échelle de Platt ou des variantes pour prédire les probabilités dans un paramètre de multiclair à un contre un autre. – ogrisel

Questions connexes