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
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
@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
Ok, grazie! – snowneji