web-dev-qa-db-fra.com

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 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?

35
David M.

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))
55
David M.