2016-01-28 9 views
13

Ich habe die xgboost-Paket in R erkundet und ging durch mehrere Demos sowie Tutorials, aber das verwirrt mich immer noch: nach der Verwendung von xgb.cv zu tun Kreuzvalidierung, wie werden die optimalen Parameter an xgb.train übergeben? Oder sollte ich die idealen Parameter (wie nround, max.depth) basierend auf der Ausgabe von xgb.cv berechnen?xgboost in R: Wie übergibt xgb.cv die optimalen Parameter 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) 

Antwort

40

Sieht aus wie Sie xgb.cv falsch verstanden, es ist kein Parameter Suchfunktion ist. Es k-faltet Kreuzvalidierung, nichts mehr.

In Ihrem Code wird der Wert param nicht geändert.

Um die besten Parameter in XGBoost von R zu finden, gibt es einige Methoden. Dies sind zwei Methoden,

(1) Verwenden Sie mlr Paket, http://mlr-org.github.io/mlr-tutorial/release/html/

Es gibt eine XGBoost + mlr example code in der Kaggle Prudential Herausforderung,

Aber dieser Code ist für Regression, nicht Klassifizierung. Soweit ich weiß, gibt es noch keine mlogloss Metrik in mlr Paket, so dass Sie die mlogloss Messung von Grund auf selbst codieren müssen. CMIIW.

(2) Zweite Methode, durch die Parameter manuell dann Einstellung wiederholen, beispielsweise

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) 

Dann finden Sie die besten (Minimum) mlogloss,

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

min_logloss ist der Minimalwert von mlogloss, während min_logloss_index der Index ist (rund).

Sie müssen den obigen Vorgang mehrmals wiederholen, jedes Mal ändern Sie die Parameter manuell (mlr macht die Wiederholung für Sie). Bis Sie schließlich das beste globale Minimum min_logloss erhalten.

Hinweis: Sie können dies in einer Schleife von 100 oder 200 Iterationen tun, in denen Sie für jede Iteration den Parameterwert zufällig festlegen. Auf diese Weise müssen Sie die besten [parameters_list, min_logloss, min_logloss_index] in Variablen oder in einer Datei speichern.

Hinweis: besser einstellen zufällige Samen von set.seed() für reproduzierbar Ergebnis. Unterschiedlicher Zufallssamen ergibt ein anderes Ergebnis. Sie müssen also [parameters_list, min_logloss, min_logloss_index, seednumber] in den Variablen oder der Datei speichern.

sagt, dass Sie schließlich 3 Ergebnisse in 3 Wiederholungen/Wiederholungen erhalten:

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

Dann müssen Sie den dritten Parameter verwenden (es globales Minimum min_logloss von 1.9745 hat). Ihr bester Index (nrounds) ist 780.

Sobald Sie am besten Parameter zu erhalten, verwenden sie in der Ausbildung,

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

Ich glaube nicht, Sie watchlist in der Ausbildung benötigen, weil Sie die Kreuzvalidierung getan haben. Aber wenn Sie immer noch watchlist verwenden möchten, ist es nur okay.

Noch besser können Sie frühen Halt in xgb.cv verwenden.

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

Mit diesem Code, wenn mlogloss Wert in 8 Schritten nicht abnimmt, stoppt der xgb.cv wird. Sie können Zeit sparen. Sie müssen maximize auf FALSE setzen, weil Sie minimalen mlogloss erwarten.

Hier ist ein Beispielcode mit 100 Iterationsschleife und zufällig ausgewählten Parametern.

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) 

Mit diesem Code führen Sie die Kreuzvalidierung 100 Mal mit jeweils zufälligen Parametern durch. Dann erhalten Sie den besten Parametersatz, dh in der Iteration mit Minimum min_logloss.

Erhöhen Sie den Wert early.stop.round, falls Sie feststellen, dass es zu klein ist (zu frühes Anhalten). Sie müssen außerdem das Limit der Zufallsparameterwerte basierend auf Ihren Datenmerkmalen ändern.

Und, für 100 oder 200 Iterationen, ich denke, Sie möchten verbose auf FALSE ändern.

Seitliche Anmerkung: Das ist ein Beispiel für eine zufällige Methode, die Sie z. durch Bayessche Optimierung für bessere Methode. Wenn Sie eine Python-Version von XGBoost haben, gibt es ein gutes Hyperparameter-Skript für XGBoost, https://github.com/mpearmain/BayesBoost, um nach den besten Parametern zu suchen, die mithilfe der Bayes'schen Optimierung festgelegt wurden.

Edit: Ich möchte 3. manuelle Methode hinzufügen, gepostet von "Davut Polat" ein Kaggle Master, in der Kaggle forum.

Edit: Wenn Sie Python und sklearn kennen, können Sie auch GridSearchCV zusammen mit xgboost.XGBClassifier oder xgboost.XGBRegressor

+0

Vielen Dank für die ausführliche Antwort, war wie das Lesen ein Lehrbuch verwenden können! Der einzige Zweck von cv in diesem Fall ist es, nrounds für dich auszuwählen, stimmt das? – snowneji

+0

@snowneji, Ja, es kann so gesagt werden, um die besten Runden auf der Grundlage bestimmter Parameter zu wählen. Denn zu kleine Rundungen sind zu wenig und zu große Rundungen sind überdimensioniert. Übrigens, wenn Sie meine Antwort nützlich finden, akzeptieren Sie sie bitte, danke. – silo

+0

Okay, Danke! – snowneji

Verwandte Themen