2014-07-07 10 views
27

Sto provando a utilizzare SGD per classificare un set di dati di grandi dimensioni. Poiché i dati sono troppo grandi per adattarsi alla memoria, mi piacerebbe utilizzare il metodo partial_fit per addestrare il classificatore. Ho selezionato un campione del set di dati (100.000 righe) che si inserisce in memoria per verificare forma vs. partial_fit:Sklearn SGDClassifier 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)) 

Poi testare entrambi classificatori con un insieme identico. Nel primo caso ottengo una precisione del 100%. A quanto ho capito, SGD per impostazione predefinita passa 5 volte rispetto ai dati di allenamento (n_iter = 5).

Nel secondo caso, devo passare 60 volte sopra i dati per ottenere la stessa precisione.

Perché questa differenza (5 contro 60)? O sto facendo qualcosa di sbagliato?

+0

Dare 'verbose = 1' al costruttore SGD, che può dare un suggerimento. –

+0

Il primo caso (fit) termina con "- Epoch 5 Norm: 29.25, NNZs: 300, Bias: -1.674706, T: 459595, Avg. Loss: 0.076786". Il secondo caso (partial_fit) dopo 10 passaggi termina con "- Epoch 1 Norm: 22.99, NNZs: 300, Bias: -1.999685, T: 1918, Avg. Loss: 0.089302". Cosa dovrei cercare? grazie –

+0

La perdita media. Controlla se cade più velocemente nel caso del lotto. –

risposta

46

Ho finalmente trovato la risposta. È necessario mischiare le dati di allenamento tra ogni iterazione, come l'impostazione riordino = True quando si crea un'istanza del modello non sarà mischiare i dati quando si utilizza partial_fit (si applica solo ai adattarsi). Nota: sarebbe stato utile trovare queste informazioni su sklearn.linear_model.SGDClassifier page.

Il codice modificato è formulato come segue:

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