J'applique scikit-learn à un modèle LDA avec beaucoup de données. Le code correspondant ressemble à ceci:
lda = LatentDirichletAllocation(n_topics = n_topics,
max_iter = iters,
learning_method = 'online',
learning_offset = offset,
random_state = 0,
evaluate_every = 5,
n_jobs = 3,
verbose = 0)
lda.fit(X)
(Je suppose que le seul détail éventuellement pertinent ici est que j'utilise plusieurs tâches.)
Après un certain temps, le message d'erreur «Il ne reste plus d'espace sur le périphérique», même s'il reste beaucoup d'espace sur le disque et beaucoup de mémoire disponible. J'ai essayé le même code plusieurs fois, sur deux ordinateurs différents (sur ma machine locale et sur un serveur distant), d'abord en utilisant python3, puis en utilisant python2, et à chaque fois, j'ai eu la même erreur.
Si je lance le même code sur un échantillon plus petit de données, tout fonctionne correctement.
La trace entière de la pile:
Failed to save <type 'numpy.ndarray'> to .npy file:
Traceback (most recent call last):
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 271, in save
obj, filename = self._write_array(obj, filename)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 231, in _write_array
self.np.save(filename, array)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/numpy/lib/npyio.py", line 491, in save
pickle_kwargs=pickle_kwargs)
File "/home/ubuntu/anaconda2/lib/python2.7/site-packages/numpy/lib/format.py", line 584, in write_array
array.tofile(fp)
IOError: 275500 requested and 210934 written
IOErrorTraceback (most recent call last)
<ipython-input-7-6af7e7c9845f> in <module>()
7 n_jobs = 3,
8 verbose = 0)
----> 9 lda.fit(X)
/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/decomposition/online_lda.pyc in fit(self, X, y)
509 for idx_slice in gen_batches(n_samples, batch_size):
510 self._em_step(X[idx_slice, :], total_samples=n_samples,
--> 511 batch_update=False, parallel=parallel)
512 else:
513 # batch update
/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/decomposition/online_lda.pyc in _em_step(self, X, total_samples, batch_update, parallel)
403 # E-step
404 _, suff_stats = self._e_step(X, cal_sstats=True, random_init=True,
--> 405 parallel=parallel)
406
407 # M-step
/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/decomposition/online_lda.pyc in _e_step(self, X, cal_sstats, random_init, parallel)
356 self.mean_change_tol, cal_sstats,
357 random_state)
--> 358 for idx_slice in gen_even_slices(X.shape[0], n_jobs))
359
360 # merge result
/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/externals/joblib/parallel.pyc in __call__(self, iterable)
808 # consumption.
809 self._iterating = False
--> 810 self.retrieve()
811 # Make sure that we get a last message telling us we are done
812 elapsed_time = time.time() - self._start_time
/home/ubuntu/anaconda2/lib/python2.7/site-packages/sklearn/externals/joblib/parallel.pyc in retrieve(self)
725 job = self._jobs.pop(0)
726 try:
--> 727 self._output.extend(job.get())
728 except Tuple(self.exceptions) as exception:
729 # Stop dispatching any new job in the async callback thread
/home/ubuntu/anaconda2/lib/python2.7/multiprocessing/pool.pyc in get(self, timeout)
565 return self._value
566 else:
--> 567 raise self._value
568
569 def _set(self, i, obj):
IOError: [Errno 28] No space left on device
Avait le même problème avec LatentDirichletAllocation
. Il semble que vous manquiez de mémoire partagée (/dev/shm
lorsque vous exécutez df -h
). Essayez de définir la variable d'environnement JOBLIB_TEMP_FOLDER
sur quelque chose de différent: par exemple, sur /tmp
. Dans mon cas, le problème a été résolu.
Ou augmentez simplement la taille de la mémoire partagée, si vous avez les droits appropriés pour la machine sur laquelle vous entraînez le LDA.
Ce problème se produit lorsque la mémoire partagée est utilisée et qu'aucune opération d'E/S n'est autorisée. C’est un problème frustrant qui concerne la plupart des utilisateurs de Kaggle lors de l’adaptation de modèles d’apprentissage automatique.
J'ai surmonté ce problème en définissant la variable JOBLIB_TEMP_FOLDER à l'aide du code suivant.
%env JOBLIB_TEMP_FOLDER=/tmp
C'est parce que vous avez défini n_jobs = 3. Vous pouvez le définir sur 1, la mémoire partagée ne sera pas utilisée, même si l'apprentissage prend plus de temps. Vous pouvez choisir de sélectionner un répertoire de cache joblib selon la réponse ci-dessus, mais gardez à l'esprit que ce cache peut également remplir rapidement votre disque, en fonction du jeu de données? et les transactions sur disque peuvent ralentir votre travail.