scikit-learn joblib bug: multiprocesamiento de valores de auto valor fuera de rango para el código de formato ‘i’, solo con matrices de gran tamaño

Mi código funciona bien con muestras de prueba más pequeñas, como 10000 filas de datos en X_train , y_train . Cuando lo llamo para millones de filas, recibo el error resultante. ¿Está el error en un paquete, o puedo hacer algo diferente? Estoy usando Python 2.7.7 de Anaconda 2.0.1, y coloco el pool.py del paquete multiprocesamiento de Anaconda y parallel.py del paquete externo de scikit-learn en mi Dropbox para usted.

El script de prueba es:

 import numpy as np import sklearn from sklearn.linear_model import SGDClassifier from sklearn import grid_search import multiprocessing as mp def main(): print("Started.") print("numpy:", np.__version__) print("sklearn:", sklearn.__version__) n_samples = 1000000 n_features = 1000 X_train = np.random.randn(n_samples, n_features) y_train = np.random.randint(0, 2, size=n_samples) print("input data size: %.3fMB" % (X_train.nbytes / 1e6)) model = SGDClassifier(penalty='elasticnet', n_iter=10, shuffle=True) param_grid = [{ 'alpha' : 10.0 ** -np.arange(1,7), 'l1_ratio': [.05, .15, .5, .7, .9, .95, .99, 1], }] gs = grid_search.GridSearchCV(model, param_grid, n_jobs=8, verbose=100) gs.fit(X_train, y_train) print(gs.grid_scores_) if __name__=='__main__': mp.freeze_support() main() 

Esto resulta en la salida:

 Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Started. ('numpy:', '1.8.1') ('sklearn:', '0.15.0b1') input data size: 8000.000MB Fitting 3 folds for each of 48 candidates, totalling 144 fits Memmaping (shape=(1000000L, 1000L), dtype=float64) to new file c:\users\laszlos\appdata\local\temp\4\joblib_memmaping_pool_6172_78765976\6172-284752304-75223296-0.pkl Failed to save  to .npy file: Traceback (most recent call last): File "C:\Anaconda\lib\site-packages\sklearn\externals\joblib\numpy_pickle.py", line 240, in save obj, filename = self._write_array(obj, filename) File "C:\Anaconda\lib\site-packages\sklearn\externals\joblib\numpy_pickle.py", line 203, in _write_array self.np.save(filename, array) File "C:\Anaconda\lib\site-packages\numpy\lib\npyio.py", line 453, in save format.write_array(fid, arr) File "C:\Anaconda\lib\site-packages\numpy\lib\format.py", line 406, in write_array array.tofile(fp) ValueError: 1000000000 requested and 268435456 written Memmaping (shape=(1000000L, 1000L), dtype=float64) to old file c:\users\laszlos\appdata\local\temp\4\joblib_memmaping_pool_6172_78765976\6172-284752304-75223296-0.pkl Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Vendor: Continuum Analytics, Inc. Package: mkl Message: trial mode expires in 28 days Traceback (most recent call last): File "S:\laszlo\gridsearch_largearray.py", line 33, in  main() File "S:\laszlo\gridsearch_largearray.py", line 28, in main gs.fit(X_train, y_train) File "C:\Anaconda\lib\site-packages\sklearn\grid_search.py", line 597, in fit return self._fit(X, y, ParameterGrid(self.param_grid)) File "C:\Anaconda\lib\site-packages\sklearn\grid_search.py", line 379, in _fit for parameters in parameter_iterable File "C:\Anaconda\lib\site-packages\sklearn\externals\joblib\parallel.py", line 651, in __call__ self.retrieve() File "C:\Anaconda\lib\site-packages\sklearn\externals\joblib\parallel.py", line 503, in retrieve self._output.append(job.get()) File "C:\Anaconda\lib\multiprocessing\pool.py", line 558, in get raise self._value struct.error: integer out of range for 'i' format code 

EDIT: la respuesta de ogrisel funciona con la asignación manual de memoria con scikit-learn-0.15.0b1. No olvide ejecutar solo un script a la vez, de lo contrario, puede quedarse sin memoria y tener demasiados hilos. (Mi ejecución toma ~ 60 GB en datos de tamaño ~ 12.5 GB en CSV, con 8 subprocesos).

Como solución alternativa, puede intentar mapear sus datos de forma explícita y manual, como se explica en la documentación de joblib .

Edit # 1: Aquí está la parte importante:

 from sklearn.externals import joblib joblib.dump(X_train, some_filename) X_train = joblib.load(some_filename, mmap_mode='r+') 

Luego pase estos datos de GridSearchCV a GridSearchCV en scikit-learn 0.15+.

Edición n. ° 2: Además, si utiliza la versión de 32 bits de Anaconda, estará limitado a 2 GB por proceso de python, que también puede limitar la memoria.

Acabo de encontrar un error para numpy.save en Python 3.4, pero incluso cuando se solucione, la siguiente llamada a mmap fallará con:

 OSError: [WinError 8] Not enough storage is available to process this command 

Entonces, use una versión de Python de 64 bits (con Anaconda como AFAIK, actualmente no hay otros paquetes de 64 bits para numpy / scipy / scikit-learn == 0.15.0b1 en este momento).

Edición nº 3: encontré otro problema que podría estar causando un uso excesivo de la memoria en Windows: actualmente joblib.Parallel memoria joblib.Parallel asigna datos de entrada con mmap_mode='c' de forma predeterminada: esta configuración de copia en escritura parece causar que las ventanas agoten la paginación archivo y, a veces, activa “[error 1455] el archivo de paginación es demasiado pequeño para que esta operación se complete” errores. Configurar mmap_mode='r' o mmap_mode='r+' no desencadena ese problema. Ejecutaré pruebas para ver si puedo cambiar el modo predeterminado en la próxima versión de joblib.