Pregunta

Una forma de entrenar una regresión logística es mediante el uso de descenso de gradiente estocástico, que Scikit-Learn ofrece una interfaz.

Lo que me gustaría hacer es tomar un Scikit-Learn's Sgdclassifier Y haga que obtenga lo mismo que una regresión logística aquí. Sin embargo, me falta algunas mejoras de aprendizaje automático, ya que mis puntajes no son equivalentes.

Este es mi código actual. ¿Qué me falta en el SGDClassifier que lo haría producir los mismos resultados que una regresión logística?

from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
import numpy as np
import pandas as pd
from sklearn.cross_validation import KFold
from sklearn.metrics import accuracy_score

# Note that the iris dataset is available in sklearn by default.
# This data is also conveniently preprocessed.
iris = datasets.load_iris()
X = iris["data"]
Y = iris["target"]

numFolds = 10
kf = KFold(len(X), numFolds, shuffle=True)

# These are "Class objects". For each Class, find the AUC through
# 10 fold cross validation.
Models = [LogisticRegression, SGDClassifier]
params = [{}, {"loss": "log", "penalty": "l2"}]
for param, Model in zip(params, Models):
    total = 0
    for train_indices, test_indices in kf:

        train_X = X[train_indices, :]; train_Y = Y[train_indices]
        test_X = X[test_indices, :]; test_Y = Y[test_indices]

        reg = Model(**param)
        reg.fit(train_X, train_Y)
        predictions = reg.predict(test_X)
        total += accuracy_score(test_Y, predictions)
    accuracy = total / numFolds
    print "Accuracy score of {0}: {1}".format(Model.__name__, accuracy)

Mi salida:

Accuracy score of LogisticRegression: 0.946666666667
Accuracy score of SGDClassifier: 0.76
¿Fue útil?

Solución

Los comentarios sobre el número de iteración son acertados. El valor por defecto SGDClassifier n_iter es 5 lo que significa que lo haces 5 * num_rows Pasos en el espacio de peso. los regla general de sklearn es ~ 1 millón de pasos para datos típicos. Para su ejemplo, simplemente configúrelo en 1000 y podría alcanzar la tolerancia primero. Tu precisión es menor con SGDClassifier Porque está alcanzando el límite de iteración antes de la tolerancia, por lo que se está "deteniendo temprano"

Modificando su código rápido y sucio, obtengo:

# Added n_iter here
params = [{}, {"loss": "log", "penalty": "l2", 'n_iter':1000}]

for param, Model in zip(params, Models):
    total = 0
    for train_indices, test_indices in kf:
        train_X = X[train_indices, :]; train_Y = Y[train_indices]
        test_X = X[test_indices, :]; test_Y = Y[test_indices]
        reg = Model(**param)
        reg.fit(train_X, train_Y)
        predictions = reg.predict(test_X)
        total += accuracy_score(test_Y, predictions)

    accuracy = total / numFolds
    print "Accuracy score of {0}: {1}".format(Model.__name__, accuracy)

Accuracy score of LogisticRegression: 0.96
Accuracy score of SGDClassifier: 0.96

Otros consejos

SGDClassifier, como su nombre indica, utiliza descenso de gradiente estocástico como algoritmo de optimización.

Si observa la implementación de logisiticregression en Sklearn, se proporcionan cinco técnicas de optimización (solucionador) y, por defecto, es 'liblineal' que utiliza descenso de coordenadas (CD) para converger.

Además del número de iteraciones, optimización, tipo de regularización (penalización) y su magnitud (c) también afectan el rendimiento del algoritmo.

Si lo está ejecutando en el ajuste de datos de Iris, todos estos hiperparametros pueden no traer un cambio significativo, pero para el conjunto de datos complejos juegan un papel significativo.

Para más, puede referir el Documentación de regresión logística de Sklearn.

También debe hacer una búsqueda de cuadrícula para el hiperparámetro "alfa" para el SGDClassifier. Se menciona explícitamente en la documentación de Sklearn y de mi experiencia tiene un gran impacto en la precisión. El segundo hiperparámetro que debe ver es "n_iter", sin embargo, vi un efecto más pequeño con mis datos.

Tl; Dr: Puede especificar una cuadrícula de alfa y nitro(o max_iter) y use parta para hiperoptimización en SGDClassifier

Mi colega, Vinay Patlolla, escribió una excelente publicación de blog en Cómo hacer que el clasificador SGD funcione tan bien como la regresión logística usando Parfit.

Parta es un paquete de optimización de hiper-paraméter que utilizó para encontrar la combinación apropiada de parámetros que sirvieron para optimizar SGDClassifier para realizar una regresión logística en su conjunto de datos de ejemplo en mucho menos tiempo.

En resumen, los dos parámetros clave para SGDClassifier son alfa y nitro. Para citar Vinay directamente:

n_iter en sklearn no es ninguno por defecto. Lo establecemos aquí en una cantidad suficientemente grande (1000). Un parámetro alternativo a N_ITER, que se ha agregado recientemente, es max_iter. El mismo consejo debe aplicarse para Max_iter.

El hiper-parámetro alfa tiene un doble propósito. Es tanto un parámetro de regularización como la tasa de aprendizaje inicial bajo el cronograma predeterminado. Esto significa que, además de regularizar los coeficientes de regresión logística, la salida del modelo depende de una interacción entre alfa y el número de épocas (n_iter) que realiza la rutina de ajuste. Específicamente, a medida que el alfa se vuelve muy pequeño, el n_iter debe aumentarse para compensar la tasa de aprendizaje lenta. Es por eso que es más seguro (pero más lento) especificar N_ITER lo suficientemente grande, por ejemplo, por ejemplo, al buscar en una amplia gama de alfas.

Licenciado bajo: CC-BY-SA con atribución
scroll top