modelos - xgboost r ejemplos
xgboost en R: cómo xgb.cv pasa los parámetros óptimos a xgb.train (2)
¡Esta es una buena pregunta y una gran respuesta del silo con muchos detalles! Lo encontré muy útil para alguien nuevo en xgboost
como yo. Gracias. El método para aleatorizar y compararlo con el límite es muy inspirador. Buen uso y bueno saber Ahora, en 2018, se necesitan algunas revisiones leves, por ejemplo, early.stop.round
debería ser early_stopping_rounds
. La salida mdcv
está organizada de forma ligeramente diferente:
min_rmse_index <- mdcv$best_iteration
min_rmse <- mdcv$evaluation_log[min_rmse_index]$test_rmse_mean
Y depende de la aplicación (lineal, logística, etc.), el objective
, eval_metric
y los parámetros se ajustarán en consecuencia.
Para la comodidad de cualquiera que esté ejecutando una regresión, aquí está la versión de código ligeramente ajustada (la mayoría son las mismas que las anteriores).
library(xgboost)
# Matrix for xgb: dtrain and dtest, "label" is the dependent variable
dtrain <- xgb.DMatrix(X_train, label = Y_train)
dtest <- xgb.DMatrix(X_test, label = Y_test)
best_param <- list()
best_seednumber <- 1234
best_rmse <- Inf
best_rmse_index <- 0
set.seed(123)
for (iter in 1:100) {
param <- list(objective = "reg:linear",
eval_metric = "rmse",
max_depth = sample(6:10, 1),
eta = runif(1, .01, .3), # Learning rate, default: 0.3
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 # 5-fold cross-validation
seed.number <- sample.int(10000, 1) # set seed for the cv
set.seed(seed.number)
mdcv <- xgb.cv(data = dtrain, params = param,
nfold = cv.nfold, nrounds = cv.nround,
verbose = F, early_stopping_rounds = 8, maximize = FALSE)
min_rmse_index <- mdcv$best_iteration
min_rmse <- mdcv$evaluation_log[min_rmse_index]$test_rmse_mean
if (min_rmse < best_rmse) {
best_rmse <- min_rmse
best_rmse_index <- min_rmse_index
best_seednumber <- seed.number
best_param <- param
}
}
# The best index (min_rmse_index) is the best "nround" in the model
nround = best_rmse_index
set.seed(best_seednumber)
xg_mod <- xgboost(data = dtest, params = best_param, nround = nround, verbose = F)
# Check error in testing data
yhat_xg <- predict(xg_mod, dtest)
(MSE_xgb <- mean((yhat_xg - Y_test)^2))
He estado explorando el paquete xgboost
en R y pasé por varias demostraciones y tutoriales, pero esto todavía me confunde: después de usar xgb.cv
para realizar la validación cruzada, ¿cómo se pasan los parámetros óptimos a xgb.train
? ¿O debería calcular los parámetros ideales (como nround
, max.depth
) según la salida de xgb.cv
?
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)
Parece que xgb.cv
mal xgb.cv
, no es una función de búsqueda de parámetros. Hace k-pliegues de validación cruzada, nada más.
En su código, no cambia el valor de param
.
Para encontrar los mejores parámetros en R''s XGBoost, hay algunos métodos. Estos son 2 métodos,
(1) Utilice el paquete mlr
, http://mlr-org.github.io/mlr-tutorial/release/html/
Hay un código de ejemplo XGBoost + mlr en el desafío Prudential de Kaggle,
Pero ese código es para regresión, no para clasificación. Hasta donde sé, no hay mlogloss
métrica de mlr
en el paquete mlr
, por lo que debe codificar la medición de mlogloss desde cero. CMIIW.
(2) Segundo método, al configurar manualmente los parámetros y luego repetir, ejemplo,
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)
Entonces, encuentras el mejor (mínimo) mlogloss,
min_logloss = min(mdcv[, test.mlogloss.mean])
min_logloss_index = which.min(mdcv[, test.mlogloss.mean])
min_logloss
es el valor mínimo de mlogloss, mientras que min_logloss_index
es el índice (round).
Debe repetir el proceso anterior varias veces, cada vez que cambie los parámetros manualmente ( mlr
lo repite por usted). Hasta que finalmente obtengas el mejor min_logloss
global.
Nota: Puede hacerlo en un bucle de 100 o 200 iteraciones, en el que para cada iteración se establece el valor de los parámetros de forma aleatoria. De esta manera, debe guardar la mejor [parameters_list, min_logloss, min_logloss_index]
en variables o en un archivo.
Nota: es mejor establecer una semilla aleatoria mediante set.seed()
para obtener un resultado reproducible . Diferentes semillas aleatorias dan resultados diferentes. Por lo tanto, debe guardar [parameters_list, min_logloss, min_logloss_index, seednumber]
en las variables o el archivo.
Digamos que finalmente obtienes 3 resultados en 3 iteraciones / repeticiones:
min_logloss = 2.1457, min_logloss_index = 840
min_logloss = 2.2293, min_logloss_index = 920
min_logloss = 1.9745, min_logloss_index = 780
Luego debe usar los terceros parámetros (tiene un mínimo global de min_logloss
de 1.9745
). Tu mejor índice (nrounds) es 780
.
Una vez que obtenga los mejores parámetros, úselo en el entrenamiento,
# 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)
No creo que necesites una watchlist
de watchlist
en el entrenamiento, porque has hecho la validación cruzada. Pero si aún quieres usar la watchlist
, está bien.
Aún mejor puedes usar la parada temprana en 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 este código, cuando el valor de mlogloss
no disminuye en 8 pasos, el xgb.cv
se detendrá. Usted puede ahorrar tiempo. Debe establecer maximize
en FALSE
, porque espera un mínimo de mlogloss.
Aquí hay un código de ejemplo, con 100 iteraciones en bucle y parámetros elegidos al azar.
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 este código, ejecuta la validación cruzada 100 veces, cada vez con parámetros aleatorios. Entonces obtienes el mejor conjunto de parámetros, que está en la iteración con un mínimo de min_logloss
.
Aumente el valor de early.stop.round
en caso de que descubra que es demasiado pequeño (detención demasiado temprana). También debe cambiar el límite de los valores de parámetros aleatorios según las características de sus datos.
Y, para 100 o 200 iteraciones, creo que desea cambiar verbose
a FALSO.
Nota al margen: este es un ejemplo de método aleatorio, puede ajustarlo, por ejemplo, mediante optimización Bayesiana para un mejor método. Si tiene la versión Python de XGBoost, hay un buen script de hiperparámetros para XGBoost, https://github.com/mpearmain/BayesBoost para buscar los mejores parámetros establecidos con la optimización Bayesiana.
Edición: Quiero agregar el tercer método manual, publicado por "Davut Polat", un maestro de Kaggle, en el foro de Kaggle .
Edición: si conoce Python y sklearn, también puede usar GridSearchCV junto con xgboost.XGBClassifier o xgboost.XGBRegressor