stochastic sklearn sgd descent python machine-learning scikit-learn gradient-descent

python - descent - sklearn sgd regression



Sklearn SGDClassifier parcial fit (1)

Estoy tratando de usar SGD para clasificar un gran conjunto de datos. Como los datos son demasiado grandes para caber en la memoria, me gustaría usar el método partial_fit para entrenar al clasificador. He seleccionado una muestra del conjunto de datos (100,000 filas) que se ajusta a la memoria para probar el ajuste en comparación con 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))

Luego pruebo ambos clasificadores con un conjunto de prueba idéntico. En el primer caso, obtengo una precisión del 100%. Según tengo entendido, SGD por defecto pasa 5 veces sobre los datos de entrenamiento (n_iter = 5).

En el segundo caso, tengo que pasar 60 veces más de los datos para alcanzar la misma precisión.

¿Por qué esta diferencia (5 contra 60)? ¿O estoy haciendo algo mal?


Finalmente encontré la respuesta. Es necesario mezclar los datos de entrenamiento entre cada iteración , como si se tratara de shuffle = True cuando al crear una instancia del modelo NO se mezclarán los datos cuando se usa partial_fit (solo se aplica al ajuste ). Nota: hubiera sido útil encontrar esta información en la página sklearn.linear_model.SGDClassifier .

El código enmendado dice lo siguiente:

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