2012-06-25 10 views
7

Estoy intentando utilizar sklearn de 0,11 objeto regresión logística para ajustar un modelo en 200.000 observaciones con alrededor de 80.000 funciones. El objetivo es clasificar las descripciones cortas de texto en 1 de 800 clases.scikit-learn Regresión logística de memoria Error

Cuando intento para adaptarse a la pythonw.exe clasificador me da:

Error de aplicación "La instrucción en ... referencia a memoria en 0x00000000". La memoria no se pudo escribir ".

Las características son extremadamente dispersas, aproximadamente 10 por observación, y son binarias (1 o 0), así que según mi cálculo del sobre, mis 4 GB de RAM deberían poder manejar los requisitos de memoria, pero ese no parece ser el caso. Los modelos solo se ajustan cuando uso menos observaciones y/o menos funciones.

En todo caso, me gustaría utilizar aún más observaciones y características. la comprensión ingenua es que la biblioteca liblinear que ejecuta cosas detrás de escena es capaz de soportar eso. ¿Alguna idea de cómo podría exprimir algunas observaciones más en?

Mi código es así:

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) 

La función de funciones() que paso al analizador solo devuelve una lista de cadenas que indican las características detectadas en cada observación.

estoy usando Python 2.7, sklearn 0.11, Windows XP con 4 GB de RAM.

+0

¿Falló el intérprete de Python? Escribir a '0x0' es un error bastante grave, nosotros (desarrolladores de scikit-learn) debemos investigarlo. –

+0

El intérprete de Python se cuelga. –

+0

¿El conjunto de datos que está utilizando es público? ¿Puede reproducir este accidente con un pequeño conjunto de datos (por ejemplo con 'x_first_half = x [: x.shape [0]/2]' 'o x_second_half = x [x.forma [0]/2:] '? – ogrisel

Respuesta

20

LIBLINEAR (la implementación respaldo de sklearn.linear_model.LogisticRegression) llevará a cabo su propia copia de los datos, ya que es una biblioteca de C++ cuyo trazado memoria interna no se puede asignar directamente en una matriz dispersa preasignados en scipy como scipy.sparse.csr_matrix o scipy.sparse.csc_matrix.

En su caso yo recomendaría para cargar sus datos como scipy.sparse.csr_matrix y alimentar a un sklearn.linear_model.SGDClassifier (con loss='log' si quieres un modelo de regresión logística y la capacidad de llamar al método predict_proba). SGDClassifier no copiará los datos de entrada si ya está utilizando el diseño scipy.sparse.csr_matrix memoria.

Espere que asigne un modelo denso de 800 * (80000 + 1) * 8/(1024 ** 2) = 488MB en la memoria (además del tamaño de su conjunto de datos de entrada).

Editar: cómo optimizar el acceso a la memoria de su conjunto de datos

Para liberar memoria después de la extracción de datos se puede:

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

continuación, salga de este proceso pitón (para forzar cancelación de asignación de memoria completa) y en un nuevo proceso:

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

En Linux/OSX puede hacer un mapa de memoria aún más eficiente con:

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

Excelente respuesta, usted ofrece un mejor soporte para este software gratuito que otros para un software muy costoso, el mundo le debe muchas gracias. Sin embargo, una pequeña nota, el método predict_proba del SGDClassifier solo parece ser implementado para 2 tareas de clasificación de categoría. –

+0

De hecho, me olvidé de eso. Actualmente existe una discusión en la lista de correo para agregar una regresión logística multinomial adecuada a SGDClassifier o para implementar la escala de Platt o variantes para predecir probabilidades en una configuración de multiclases de uno contra el resto. – ogrisel

Cuestiones relacionadas