Sklearn SGDClassifier ajustement partiel
J'essaie D'utiliser SGD pour classer un grand ensemble de données. Comme les données sont trop volumineuses pour tenir dans la mémoire, je voudrais utiliser la méthode partial_fit pour former le classificateur. J'ai sélectionné un échantillon de l'ensemble de données (100 000 lignes) qui s'intègre dans la mémoire pour tester fit vs. partial_fit :
from sklearn.linear_model import SGDClassifier
def batches(l, n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
clf1 = SGDClassifier(shuffle=True, loss='log')
clf1.fit(X, Y)
clf2 = SGDClassifier(shuffle=True, loss='log')
n_iter = 60
for n in range(n_iter):
for batch in batches(range(len(X)), 10000):
clf2.partial_fit(X[batch[0]:batch[-1]+1], Y[batch[0]:batch[-1]+1], classes=numpy.unique(Y))
Je teste ensuite les deux classificateurs avec un ensemble de tests identique. Dans le premier cas, j'obtiens une précision de 100%. Si je comprends bien, SGD passe par défaut 5 fois sur les données de formation (n_iter = 5).
Dans le second cas, je dois passer 60 fois sur les données pour atteindre la même précision.
Pourquoi cette différence (5 contre 60)? Ou est-ce que je fais quelque chose de mal?
1 réponses
, j'ai enfin trouvé la réponse. Vous devez Mélanger les données d'apprentissage entre chaque itération , car le paramètre shuffle=True lors de l'instanciation du modèle ne mélangera pas les données lors de l'utilisation de partial_fit (il ne s'applique qu'à fit). Remarque: il aurait été utile de trouver cette information sur le sklearn .linear_model.SGDClassifier page .
Le code modifié se lit comme suit:
from sklearn.linear_model import SGDClassifier
import random
clf2 = SGDClassifier(loss='log') # shuffle=True is useless here
shuffledRange = range(len(X))
n_iter = 5
for n in range(n_iter):
random.shuffle(shuffledRange)
shuffledX = [X[i] for i in shuffledRange]
shuffledY = [Y[i] for i in shuffledRange]
for batch in batches(range(len(shuffledX)), 10000):
clf2.partial_fit(shuffledX[batch[0]:batch[-1]+1], shuffledY[batch[0]:batch[-1]+1], classes=numpy.unique(Y))