J'essaie d'utiliser SGD pour classer un grand ensemble de données. Comme les données sont trop volumineuses pour tenir en mémoire, j'aimerais 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 tient 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 par défaut passe 5 fois sur les données d'entraînement (n_iter = 5).
Dans le deuxième cas, je dois passer 60 fois 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?
J'ai enfin trouvé la réponse. Vous devez mélanger les données d'entraînement entre chaque itération , en définissant shuffle = True lorsque l'instanciation du modèle ne sera pas mélangée les données lors de l'utilisation de partial_fit (cela ne s'applique qu'à fit). Remarque: il aurait été utile de trouver ces informations sur la page sklearn.linear_model.SGDClassifier .
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))