Scikit-learn: far prevedere SGDClassifier e una regressione logistica


24

Un modo per addestrare una regressione logistica consiste nell'utilizzare la discesa graduale stocastica, a cui scikit-learn offre un'interfaccia.

Quello che vorrei fare è prendere un SGDClassifier di scikit-learn e farlo segnare come una regressione logistica qui . Tuttavia, devo mancare alcuni miglioramenti dell'apprendimento automatico, poiché i miei punteggi non sono equivalenti.

Questo è il mio codice attuale. Cosa mi manca su SGDClassifier che avrebbe prodotto gli stessi risultati di una regressione logistica?

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)

La mia uscita:

Accuracy score of LogisticRegression: 0.946666666667
Accuracy score of SGDClassifier: 0.76

3
Una domanda e un'osservazione: quanto è stabile la tua precisione di SGD su corse ripetute? i due algoritmi non sono equivalenti e non produrranno necessariamente la stessa accuratezza dati gli stessi dati. Praticamente potresti provare a cambiare le epoche e / o il tasso di apprendimento per SGD. Oltre a ciò, potresti provare a normalizzare le funzionalità di SGD.
image_doctor

Quindi, non ho testato l'SGD su corse ripetute perché quanto sopra utilizza una validazione incrociata di 10 volte; per me è bastato.
hlin117,

Puoi spiegarmi come mai questi algoritmi non sono equivalenti? Se guardo SGDClassifier qui, menziona "La perdita 'log' dà la regressione logistica, un classificatore probabilistico". Credo che ci sia un vuoto nella mia conoscenza dell'apprendimento automatico.
hlin117,

Senza uno studio dettagliato delle implementazioni non credo di poter essere specifico sul perché non siano equivalenti, ma un buon indizio del fatto che non sono equivalenti è che i risultati per ciascun metodo sono significativamente diversi. La mia ipotesi sarebbe che abbia a che fare con le proprietà di convergenza dei metodi di stima utilizzati in ciascuno.
image_doctor il

1
Questi algoritmi sono diversi perché la regressione logistica utilizza la discesa gradiente, mentre la discesa gradiente stocastica utilizza la discesa gradiente stocastica. La convergenza della prima sarà più efficiente e produrrà risultati migliori. Tuttavia, con l'aumentare delle dimensioni del set di dati, SGDC dovrebbe avvicinarsi all'accuratezza della regressione logistica. I parametri per GD significano cose diverse rispetto ai parametri per SGD, quindi dovresti provare a regolarli leggermente. Suggerirei di giocare un po 'con (diminuendo) i tassi di apprendimento della SGD per cercare di ottenere una migliore convergenza in quanto potrebbe rallentare un po'.
AN6U5,

Risposte:


23

I commenti sul numero di iterazione sono esatti. L'impostazione predefinita SGDClassifier n_iterindica 5che si eseguono 5 * num_rowspassaggi nello spazio di peso. La regola empirica di sklearn è ~ 1 milione di passaggi per i dati tipici. Per il tuo esempio, basta impostarlo su 1000 e potrebbe raggiungere prima la tolleranza. La tua precisione è inferiore SGDClassifierperché colpisce il limite di iterazione prima della tolleranza, quindi ti stai "fermando presto"

Modificando il tuo codice veloce e sporco ottengo:

# 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

4

SGDClassifier, come suggerisce il nome, utilizza la discesa gradiente stocastico come algoritmo di ottimizzazione.

Se guardi l'implementazione di LogisiticRegression in Sklearn ci sono cinque tecniche di ottimizzazione (risolutore) fornite e per impostazione predefinita è 'LibLinear' che usa Coordinate Descent (CD) per convergere.

Oltre al numero di iterazioni, l'ottimizzazione, il tipo di regolarizzazione (penalità) e la sua grandezza (C) influiscono anche sulle prestazioni dell'algoritmo.

Se lo si esegue sulla messa a punto del set di dati Iris, tutti questi iperparametri potrebbero non apportare cambiamenti significativi, ma per set di dati complessi svolgono un ruolo significativo.

Per ulteriori informazioni, è possibile consultare la documentazione relativa alla regressione logistica di Sklearn .


3

È inoltre necessario eseguire una ricerca in griglia per l'iperparametro "alfa" per SGDClassifier. È esplicitamente menzionato nella documentazione di sklearn e dalla mia esperienza ha un grande impatto sull'accuratezza. Il secondo iperparametro che dovresti guardare è "n_iter" - tuttavia ho visto un effetto minore con i miei dati.


1

TL; DR : è possibile specificare una griglia di alpha e n_iter (o max_iter ) e utilizzare parfit per l'iperottimizzazione su SGDClassifier

Il mio collega, Vinay Patlolla, ha scritto un eccellente post sul blog su Come far funzionare il classificatore SGD e la regressione logistica usando parfit .

Parfit è un pacchetto di ottimizzazione di iperparametri che ha utilizzato per trovare la combinazione appropriata di parametri che serviva a ottimizzare SGDClassifier da eseguire così come la regressione logistica sul suo set di dati di esempio in molto meno tempo.

In sintesi, i due parametri chiave per SGDClassifier sono alpha e n_iter . Per citare direttamente Vinay:

n_iter in sklearn è Nessuno per impostazione predefinita. Lo stiamo impostando qui su un importo sufficientemente grande (1000). Un parametro alternativo a n_iter, che è stato aggiunto di recente, è max_iter. Lo stesso consiglio dovrebbe valere per max_iter.

L'iperparametro alfa ha un duplice scopo. È sia un parametro di regolarizzazione che la velocità di apprendimento iniziale secondo la pianificazione predefinita. Ciò significa che, oltre a regolarizzare i coefficienti di regressione logistica, l'output del modello dipende da un'interazione tra alfa e il numero di epoche (n_iter) eseguite dalla routine di adattamento. In particolare, poiché l'alfa diventa molto piccola, è necessario aumentare n_iter per compensare il lento tasso di apprendimento. Questo è il motivo per cui è più sicuro (ma più lento) specificare n_iter sufficientemente grande, ad esempio 1000, quando si cerca su una vasta gamma di alfa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.