L'accuratezza della macchina con incremento gradiente diminuisce all'aumentare del numero di iterazioni


15

Sto sperimentando l'algoritmo della macchina per aumentare il gradiente tramite il caretpacchetto in R.

Utilizzando un piccolo set di dati di ammissione al college, ho eseguito il seguente codice:

library(caret)

### Load admissions dataset. ###
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")

### Create yes/no levels for admission. ### 
mydata$admit_factor[mydata$admit==0] <- "no"
mydata$admit_factor[mydata$admit==1] <- "yes"             

### Gradient boosting machine algorithm. ###
set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(5000,1000000,5000), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

e ho scoperto con mia sorpresa che l'accuratezza della validazione incrociata del modello è diminuita anziché aumentata con l'aumentare del numero di iterazioni di boosting, raggiungendo una precisione minima di circa .59 a ~ 450.000 iterations.

inserisci qui la descrizione dell'immagine

Ho implementato erroneamente l'algoritmo GBM?

EDIT: seguendo il suggerimento di Underminer, ho rieseguito il caretcodice sopra ma mi sono concentrato sull'esecuzione da 100 a 5.000 iterazioni potenziate:

set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(100,5000,100), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

Il diagramma risultante mostra che l'accuratezza raggiunge un picco di quasi .705 a ~ 1.800 iterazioni:

inserisci qui la descrizione dell'immagine

La cosa curiosa è che l'accuratezza non ha raggiunto il plateau a ~ .70 ma è invece diminuita dopo 5.000 iterazioni.

Risposte:


14

In generale, l'aumento dell'errore può aumentare con il numero di iterazioni, in particolare quando i dati sono rumorosi (ad esempio casi con etichetta errata). Questo potrebbe essere il tuo problema, ma non sarei in grado di dirlo senza sapere di più sui tuoi dati

Fondamentalmente, il potenziamento può "concentrarsi" sulla previsione corretta dei casi che contengono disinformazione e, nel processo, deteriorare le prestazioni medie su altri casi che sono più sostanziali.

Questo link ( Boosting and Noise ) mostra una descrizione migliore di quella che posso fornire sul problema.

Questo documento ( Random Classification Noise ) di Long e Servedio fornisce ulteriori dettagli tecnici del problema.


16

Quello che hai visualizzato è un classico esempio di overfitting. Il piccolo aumento dell'errore deriva da prestazioni peggiori nella parte di convalida del set di dati con convalida incrociata. Più iterazioni dovrebbero quasi sempre migliorare l'errore sul set di training, ma è vero il contrario per il set di validazione / test.


Quindi overfit con incremento graduale basato sul numero di iterazioni potenziate? Interessante. Ho pensato che l'accuratezza avrebbe invece toccato il massimo dopo aver colpito il numero ottimale di iterazioni.
RobertF,

4
È corretto. Nel potenziamento del gradiente, ogni albero successivo viene creato dai residui degli alberi precedenti, quindi il GBM continuerà a provare a eliminare l'errore residuo sul set di dati di addestramento anche a costo di poter generalizzare a set di validazione / test. Ecco perché esegui la convalida incrociata - perché l'algoritmo di adattamento non sa in modo nativo quando fermarsi
Ryan Zotti

1
Il Gradient Boosting è ispirato da AdaBoost. AdaBoost si veste molto raramente e quando lo fa, è solo leggermente e dopo molte, molte iterazioni. Penso che la spiegazione di @Underminer abbia più probabilità di essere rappresentativa di ciò che sta accadendo rispetto a questo commento, soprattutto considerando che non ci sono riferimenti in questo commento.
Ricardo Cruz,

2
@RicardoCruz Penso che sia interessante che tu abbia visto raramente un eccesso di vestibilità a gradiente. Nel corso di circa quattro anni che l'ho usato, ho visto il contrario: troppi alberi portano a un eccesso di adattamento. Una volta ho dovuto dimostrare qualcosa di simile a un collega e sono stato in grado di ridurre quasi a zero l'errore sul set di addestramento, ma l'errore di convalida è aumentato in modo significativo rispetto a quello del GBM non overfit. Penso ancora che il potenziamento del gradiente sia un ottimo algoritmo. Di solito è il primo algoritmo che uso - devi solo stare attento a troppi alberi, che puoi monitorare tramite validazione incrociata
Ryan Zotti

2
@RyanZotti Sono corretto allora. Ho letto un sacco di articoli su AdaBoost di Schapire et al perché mi piacciono le sue meravigliose solide basi teoriche. Gli autori sostengono che il potenziamento è soggetto a un eccesso di adattamento, ma che è estremamente difficile. Non ho molta esperienza nell'usarlo, e non hanno una solida base teorica per argomentare questo, e, naturalmente, gli autori sono autori, sono naturalmente zelanti della loro invenzione, quindi se hai esperienza del contrario , Sono corretto.
Ricardo Cruz,

4

Codici per riprodurre un risultato simile, senza ricerca in griglia,

mod = gbm(admit ~ .,
      data = mydata[,-5],
      n.trees=100000,
      shrinkage=0.001,
      interaction.depth=2,
      n.minobsinnode=10,
      cv.folds=5,
      verbose=TRUE,
      n.cores=2)

best.iter <- gbm.perf(mod, method="OOB", plot.it=TRUE, oobag.curve=TRUE, overlay=TRUE)
print(best.iter)
[1] 1487
pred = as.integer(predict(mod, newdata=mydata[,-5], n.trees=best.iter) > 0)
y = mydata[,1]
sum(pred == y)/length(y)
[1] 0.7225

3

Il pacchetto gbm ha una funzione per stimare il numero ottimale di iterazioni (= # di alberi o # di funzioni di base),

gbm.perf(mod, method="OOB", plot.it=TRUE, oobag=TRUE, overlay=TRUE)

Non hai bisogno del treno per il guardiano.


Non so se questo risolva il problema che sto riscontrando: sembra che il numero ottimale di iterazioni sia 5.000 nel mio caso in cui l'accuratezza è massima, vicino a 0,70 (il primo punto dati nella mia trama). Ma sembra sbagliato. Più iterazioni dovrebbero portare a una maggiore precisione, non inferiore, giusto?
RobertF,

1
@RobertF In primo luogo, penso che non sia necessario trasformare l'ammissione in un fattore. Funziona altrettanto bene: mod = gbm (ammetti ~., Data = mydata [, - 5], n.trees = 100000, riduzione = 0,001, interazione.depth = 2, n.minobsinnode = 10, cv.folds = 5 , verbose = TRUE, n.cores = 2). Puoi vedere dove gbm sceglie l'iter ottimale da: best.iter <- gbm.perf (mod, method = "OOB", plot.it = TRUE, oobag.curve = TRUE, overlay = TRUE). Cioè, quando il cambiamento di devianza diventa negativo (vedi la trama generata da questo).
horaceT

1
@RobertF Un'altra cosa. Specificando n.trees = (un milione) nella chiamata gbm, avresti eseguito tutti i numeri di iterazioni da 1 a 1.000.000. Quindi non hai bisogno di cura per farlo.
horaceT

1
@RobertF Altro seguito. Ho appena eseguito 100k alberi / iterazioni. La precisione che ho ottenuto scegliendo la migliore iterazione con gbm.perf è 0,7225, che è abbastanza vicina alla tua eseguendo una griglia completa di iterazioni.
horaceT
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.