2016-01-28 10 views
13

Ho esplorato il pacchetto xgboost in R e ho analizzato diversi demo e tutorial, ma questo mi confonde ancora: dopo aver usato xgb.cv da fare convalida incrociata, come vengono passati i parametri ottimali a xgb.train? O dovrei calcolare i parametri ideali (come nround, max.depth) in base all'uscita di xgb.cv?xgboost in R: in che modo xgb.cv passa i parametri ottimali in xgb.train

param <- list("objective" = "multi:softprob", 
       "eval_metric" = "mlogloss", 
       "num_class" = 12) 
cv.nround <- 11 
cv.nfold <- 5 
mdcv <-xgb.cv(data=dtrain,params = param,nthread=6,nfold = cv.nfold,nrounds = cv.nround,verbose = T) 

md <-xgb.train(data=dtrain,params = param,nround = 80,watchlist = list(train=dtrain,test=dtest),nthread=6) 

risposta

40

Sembra che tu frainteso xgb.cv, non è una funzione di parametro di ricerca. Fa k-fold cross validation, niente di più.

Nel codice, non modifica il valore di param.

Per trovare i migliori parametri in XGBoost di R, ci sono alcuni metodi. Questi sono 2 metodi,

usare il pacchetto (1) mlr, http://mlr-org.github.io/mlr-tutorial/release/html/

C'è un XGBoost + MLR example code nella sfida Prudential del Kaggle,

Ma questo codice è per la regressione, non la classificazione. Per quanto ne so, non esiste ancora la metrica mlogloss nel pacchetto mlr, quindi è necessario codificare da zero la misurazione mlogloss da zero. CMIIW.

(2) Secondo metodo, impostando manualmente i parametri quindi ripetere, ad esempio,

param <- list(objective = "multi:softprob", 
     eval_metric = "mlogloss", 
     num_class = 12, 
     max_depth = 8, 
     eta = 0.05, 
     gamma = 0.01, 
     subsample = 0.9, 
     colsample_bytree = 0.8, 
     min_child_weight = 4, 
     max_delta_step = 1 
    ) 
cv.nround = 1000 
cv.nfold = 5 
mdcv <- xgb.cv(data=dtrain, params = param, nthread=6, 
       nfold=cv.nfold, nrounds=cv.nround, 
       verbose = T) 

Poi, a trovare la migliore (minimo) mlogloss,

min_logloss = min(mdcv[, test.mlogloss.mean]) 
min_logloss_index = which.min(mdcv[, test.mlogloss.mean]) 

min_logloss è il valore minimo di mlogloss, mentre min_logloss_index è l'indice (rotondo).

È necessario ripetere la procedura più volte, ogni volta modificare i parametri manualmente (mlr esegue la ripetizione per l'utente). Fino a quando non ottieni il miglior minimo globale min_logloss.

Nota: È possibile farlo in un ciclo di 100 o 200 iterazioni, in cui per ogni iterazione si imposta a caso il valore dei parametri. In questo modo, è necessario salvare il migliore [parameters_list, min_logloss, min_logloss_index] in variabili o in un file.

Nota: meglio impostare seme casuale da set.seed() per riproducibili risultato. Semi casuali diversi producono risultati diversi. Pertanto, è necessario salvare [parameters_list, min_logloss, min_logloss_index, seednumber] nelle variabili o nel file.

dire che finalmente si ottiene 3 risultati in 3 iterazioni/ripetizioni:

min_logloss = 2.1457, min_logloss_index = 840 
min_logloss = 2.2293, min_logloss_index = 920 
min_logloss = 1.9745, min_logloss_index = 780 

Poi è necessario utilizzare il terzo parametro (ha minimo globale min_logloss di 1.9745). Il tuo indice migliore (nrounds) è 780.

Una volta arrivati ​​migliori parametri, utilizza nella formazione,

# best_param is global best param with minimum min_logloss 
# best_min_logloss_index is the global minimum logloss index 
nround = 780 
md <- xgb.train(data=dtrain, params=best_param, nrounds=nround, nthread=6) 

Non credo che avete bisogno di watchlist nella formazione, perché hai fatto la convalida incrociata. Ma se vuoi ancora usare watchlist, va bene.

Ancora meglio è possibile utilizzare l'arresto anticipato in xgb.cv.

mdcv <- xgb.cv(data=dtrain, params=param, nthread=6, 
       nfold=cv.nfold, nrounds=cv.nround, 
       verbose = T, early.stop.round=8, maximize=FALSE) 

Con questo codice, quando mlogloss valore non diminuisce in 8 punti, la xgb.cv si fermerà. Puoi risparmiare tempo. È necessario impostare maximize su FALSE, poiché si prevede un valore minimo di mlogloss.

Ecco un codice di esempio, con 100 cicli di iterazioni e parametri scelti casualmente.

best_param = list() 
best_seednumber = 1234 
best_logloss = Inf 
best_logloss_index = 0 

for (iter in 1:100) { 
    param <- list(objective = "multi:softprob", 
      eval_metric = "mlogloss", 
      num_class = 12, 
      max_depth = sample(6:10, 1), 
      eta = runif(1, .01, .3), 
      gamma = runif(1, 0.0, 0.2), 
      subsample = runif(1, .6, .9), 
      colsample_bytree = runif(1, .5, .8), 
      min_child_weight = sample(1:40, 1), 
      max_delta_step = sample(1:10, 1) 
     ) 
    cv.nround = 1000 
    cv.nfold = 5 
    seed.number = sample.int(10000, 1)[[1]] 
    set.seed(seed.number) 
    mdcv <- xgb.cv(data=dtrain, params = param, nthread=6, 
        nfold=cv.nfold, nrounds=cv.nround, 
        verbose = T, early.stop.round=8, maximize=FALSE) 

    min_logloss = min(mdcv[, test.mlogloss.mean]) 
    min_logloss_index = which.min(mdcv[, test.mlogloss.mean]) 

    if (min_logloss < best_logloss) { 
     best_logloss = min_logloss 
     best_logloss_index = min_logloss_index 
     best_seednumber = seed.number 
     best_param = param 
    } 
} 

nround = best_logloss_index 
set.seed(best_seednumber) 
md <- xgb.train(data=dtrain, params=best_param, nrounds=nround, nthread=6) 

Con questo codice, si esegue la convalida incrociata 100 volte, ogni volta con parametri casuali. Quindi ottieni il miglior set di parametri, ovvero nell'iterazione con il minimo min_logloss.

Aumentare il valore di early.stop.round se si scopre che è troppo piccolo (arresto troppo rapido). È inoltre necessario modificare il limite dei valori dei parametri casuali in base alle caratteristiche dei dati.

E, per 100 o 200 iterazioni, penso che si voglia modificare verbose in FALSE.

Nota a margine: Questo è un esempio di metodo casuale, è possibile regolarlo ad es. dall'ottimizzazione bayesiana per un metodo migliore. Se hai la versione Python di XGBoost, c'è un buon script hyperparameter per XGBoost, https://github.com/mpearmain/BayesBoost per cercare i migliori parametri impostati usando l'ottimizzazione bayesiana.

Modifica: desidero aggiungere il terzo metodo manuale, pubblicato da "Davut Polat" un master di Kaggle, nel numero Kaggle forum.

Edit: Se si conosce Python e sklearn, è anche possibile utilizzare GridSearchCV con xgboost.XGBClassifier o xgboost.XGBRegressor

+0

Grazie per la risposta dettagliata, era come leggere un libro di testo! Quindi l'unico scopo di cv in questo caso è selezionare i dintorni per te, è corretto? – snowneji

+0

@snowneji, Sì, si può dire così, per scegliere i migliori in base a determinati parametri impostati. Perché, troppo piccoli nround sono underfitting, e troppo grandi nround si sovrascrivono. A proposito, se hai trovato la mia risposta è utile, per favore accettala, grazie. – silo

+0

Ok, grazie! – snowneji

Problemi correlati