[R] Rename watchlist -> evals (#10032)
This commit is contained in:
parent
2c13f90384
commit
b023a253b4
@ -56,10 +56,10 @@
|
|||||||
#' For \link{xgb.cv}, folds are a list with a structure as follows:\itemize{
|
#' For \link{xgb.cv}, folds are a list with a structure as follows:\itemize{
|
||||||
#' \item `dtrain`: The training data for the fold (as an `xgb.DMatrix` object).
|
#' \item `dtrain`: The training data for the fold (as an `xgb.DMatrix` object).
|
||||||
#' \item `bst`: Rhe `xgb.Booster` object for the fold.
|
#' \item `bst`: Rhe `xgb.Booster` object for the fold.
|
||||||
#' \item `watchlist`: A list with two DMatrices, with names `train` and `test`
|
#' \item `evals`: A list containing two DMatrices, with names `train` and `test`
|
||||||
#' (`test` is the held-out data for the fold).
|
#' (`test` is the held-out data for the fold).
|
||||||
#' \item `index`: The indices of the hold-out data for that fold (base-1 indexing),
|
#' \item `index`: The indices of the hold-out data for that fold (base-1 indexing),
|
||||||
#' from which the `test` entry in the watchlist was obtained.
|
#' from which the `test` entry in `evals` was obtained.
|
||||||
#' }
|
#' }
|
||||||
#'
|
#'
|
||||||
#' This object should \bold{not} be in-place modified in ways that conflict with the
|
#' This object should \bold{not} be in-place modified in ways that conflict with the
|
||||||
@ -78,7 +78,7 @@
|
|||||||
#' Note that, for \link{xgb.cv}, this will be the full data, while data for the specific
|
#' Note that, for \link{xgb.cv}, this will be the full data, while data for the specific
|
||||||
#' folds can be found in the `model` object.
|
#' folds can be found in the `model` object.
|
||||||
#'
|
#'
|
||||||
#' \item watchlist The evaluation watchlist, as passed under argument `watchlist` to
|
#' \item evals The evaluation data, as passed under argument `evals` to
|
||||||
#' \link{xgb.train}.
|
#' \link{xgb.train}.
|
||||||
#'
|
#'
|
||||||
#' For \link{xgb.cv}, this will always be `NULL`.
|
#' For \link{xgb.cv}, this will always be `NULL`.
|
||||||
@ -101,15 +101,15 @@
|
|||||||
#' \item iteration Index of the iteration number that is being executed (first iteration
|
#' \item iteration Index of the iteration number that is being executed (first iteration
|
||||||
#' will be the same as parameter `begin_iteration`, then next one will add +1, and so on).
|
#' will be the same as parameter `begin_iteration`, then next one will add +1, and so on).
|
||||||
#'
|
#'
|
||||||
#' \item iter_feval Evaluation metrics for the `watchlist` that was supplied, either
|
#' \item iter_feval Evaluation metrics for `evals` that were supplied, either
|
||||||
#' determined by the objective, or by parameter `feval`.
|
#' determined by the objective, or by parameter `feval`.
|
||||||
#'
|
#'
|
||||||
#' For \link{xgb.train}, this will be a named vector with one entry per element in
|
#' For \link{xgb.train}, this will be a named vector with one entry per element in
|
||||||
#' `watchlist`, where the names are determined as 'watchlist name' + '-' + 'metric name' - for
|
#' `evals`, where the names are determined as 'evals name' + '-' + 'metric name' - for
|
||||||
#' example, if `watchlist` contains an entry named "tr" and the metric is "rmse",
|
#' example, if `evals` contains an entry named "tr" and the metric is "rmse",
|
||||||
#' this will be a one-element vector with name "tr-rmse".
|
#' this will be a one-element vector with name "tr-rmse".
|
||||||
#'
|
#'
|
||||||
#' For \link{xgb.cv}, this will be a 2d matrix with dimensions `[length(watchlist), nfolds]`,
|
#' For \link{xgb.cv}, this will be a 2d matrix with dimensions `[length(evals), nfolds]`,
|
||||||
#' where the row names will follow the same naming logic as the one-dimensional vector
|
#' where the row names will follow the same naming logic as the one-dimensional vector
|
||||||
#' that is passed in \link{xgb.train}.
|
#' that is passed in \link{xgb.train}.
|
||||||
#'
|
#'
|
||||||
@ -169,18 +169,18 @@
|
|||||||
#' }
|
#' }
|
||||||
#' @examples
|
#' @examples
|
||||||
#' # Example constructing a custom callback that calculates
|
#' # Example constructing a custom callback that calculates
|
||||||
#' # squared error on the training data, without a watchlist,
|
#' # squared error on the training data (no separate test set),
|
||||||
#' # and outputs the per-iteration results.
|
#' # and outputs the per-iteration results.
|
||||||
#' ssq_callback <- xgb.Callback(
|
#' ssq_callback <- xgb.Callback(
|
||||||
#' cb_name = "ssq",
|
#' cb_name = "ssq",
|
||||||
#' f_before_training = function(env, model, data, watchlist,
|
#' f_before_training = function(env, model, data, evals,
|
||||||
#' begin_iteration, end_iteration) {
|
#' begin_iteration, end_iteration) {
|
||||||
#' # A vector to keep track of a number at each iteration
|
#' # A vector to keep track of a number at each iteration
|
||||||
#' env$logs <- rep(NA_real_, end_iteration - begin_iteration + 1)
|
#' env$logs <- rep(NA_real_, end_iteration - begin_iteration + 1)
|
||||||
#' },
|
#' },
|
||||||
#' f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
#' f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
#' # This calculates the sum of squared errors on the training data.
|
#' # This calculates the sum of squared errors on the training data.
|
||||||
#' # Note that this can be better done by passing a 'watchlist' entry,
|
#' # Note that this can be better done by passing an 'evals' entry,
|
||||||
#' # but this demonstrates a way in which callbacks can be structured.
|
#' # but this demonstrates a way in which callbacks can be structured.
|
||||||
#' pred <- predict(model, data)
|
#' pred <- predict(model, data)
|
||||||
#' err <- pred - getinfo(data, "label")
|
#' err <- pred - getinfo(data, "label")
|
||||||
@ -196,7 +196,7 @@
|
|||||||
#' # A return value of 'TRUE' here would signal to finalize the training
|
#' # A return value of 'TRUE' here would signal to finalize the training
|
||||||
#' return(FALSE)
|
#' return(FALSE)
|
||||||
#' },
|
#' },
|
||||||
#' f_after_training = function(env, model, data, watchlist, iteration,
|
#' f_after_training = function(env, model, data, evals, iteration,
|
||||||
#' final_feval, prev_cb_res) {
|
#' final_feval, prev_cb_res) {
|
||||||
#' return(env$logs)
|
#' return(env$logs)
|
||||||
#' }
|
#' }
|
||||||
@ -220,10 +220,10 @@
|
|||||||
xgb.Callback <- function(
|
xgb.Callback <- function(
|
||||||
cb_name = "custom_callback",
|
cb_name = "custom_callback",
|
||||||
env = new.env(),
|
env = new.env(),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) NULL,
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) NULL,
|
||||||
f_before_iter = function(env, model, data, watchlist, iteration) NULL,
|
f_before_iter = function(env, model, data, evals, iteration) NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) NULL,
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) NULL,
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) NULL
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) NULL
|
||||||
) {
|
) {
|
||||||
stopifnot(is.null(f_before_training) || is.function(f_before_training))
|
stopifnot(is.null(f_before_training) || is.function(f_before_training))
|
||||||
stopifnot(is.null(f_before_iter) || is.function(f_before_iter))
|
stopifnot(is.null(f_before_iter) || is.function(f_before_iter))
|
||||||
@ -251,7 +251,7 @@ xgb.Callback <- function(
|
|||||||
callbacks,
|
callbacks,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
begin_iteration,
|
begin_iteration,
|
||||||
end_iteration
|
end_iteration
|
||||||
) {
|
) {
|
||||||
@ -261,7 +261,7 @@ xgb.Callback <- function(
|
|||||||
callback$env,
|
callback$env,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
begin_iteration,
|
begin_iteration,
|
||||||
end_iteration
|
end_iteration
|
||||||
)
|
)
|
||||||
@ -273,7 +273,7 @@ xgb.Callback <- function(
|
|||||||
callbacks,
|
callbacks,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration
|
iteration
|
||||||
) {
|
) {
|
||||||
if (!length(callbacks)) {
|
if (!length(callbacks)) {
|
||||||
@ -287,7 +287,7 @@ xgb.Callback <- function(
|
|||||||
cb$env,
|
cb$env,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration
|
iteration
|
||||||
)
|
)
|
||||||
if (!NROW(should_stop)) {
|
if (!NROW(should_stop)) {
|
||||||
@ -304,7 +304,7 @@ xgb.Callback <- function(
|
|||||||
callbacks,
|
callbacks,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
iter_feval
|
iter_feval
|
||||||
) {
|
) {
|
||||||
@ -319,7 +319,7 @@ xgb.Callback <- function(
|
|||||||
cb$env,
|
cb$env,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
iter_feval
|
iter_feval
|
||||||
)
|
)
|
||||||
@ -337,7 +337,7 @@ xgb.Callback <- function(
|
|||||||
callbacks,
|
callbacks,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
final_feval,
|
final_feval,
|
||||||
prev_cb_res
|
prev_cb_res
|
||||||
@ -355,7 +355,7 @@ xgb.Callback <- function(
|
|||||||
cb$env,
|
cb$env,
|
||||||
model,
|
model,
|
||||||
data,
|
data,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
final_feval,
|
final_feval,
|
||||||
getElement(old_cb_res, cb$cb_name)
|
getElement(old_cb_res, cb$cb_name)
|
||||||
@ -428,7 +428,7 @@ xgb.cb.print.evaluation <- function(period = 1, showsd = TRUE) {
|
|||||||
env = as.environment(list(period = period, showsd = showsd, is_first_call = TRUE)),
|
env = as.environment(list(period = period, showsd = showsd, is_first_call = TRUE)),
|
||||||
f_before_training = NULL,
|
f_before_training = NULL,
|
||||||
f_before_iter = NULL,
|
f_before_iter = NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
if (is.null(iter_feval)) {
|
if (is.null(iter_feval)) {
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
}
|
}
|
||||||
@ -439,7 +439,7 @@ xgb.cb.print.evaluation <- function(period = 1, showsd = TRUE) {
|
|||||||
env$is_first_call <- FALSE
|
env$is_first_call <- FALSE
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
if (is.null(final_feval)) {
|
if (is.null(final_feval)) {
|
||||||
return(NULL)
|
return(NULL)
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ xgb.cb.print.evaluation <- function(period = 1, showsd = TRUE) {
|
|||||||
#' @title Callback for logging the evaluation history
|
#' @title Callback for logging the evaluation history
|
||||||
#' @return An `xgb.Callback` object, which can be passed to \link{xgb.train} or \link{xgb.cv}.
|
#' @return An `xgb.Callback` object, which can be passed to \link{xgb.train} or \link{xgb.cv}.
|
||||||
#' @details This callback creates a table with per-iteration evaluation metrics (see parameters
|
#' @details This callback creates a table with per-iteration evaluation metrics (see parameters
|
||||||
#' `watchlist` and `feval` in \link{xgb.train}).
|
#' `evals` and `feval` in \link{xgb.train}).
|
||||||
#' @details
|
#' @details
|
||||||
#' Note: in the column names of the final data.table, the dash '-' character is replaced with
|
#' Note: in the column names of the final data.table, the dash '-' character is replaced with
|
||||||
#' the underscore '_' in order to make the column names more like regular R identifiers.
|
#' the underscore '_' in order to make the column names more like regular R identifiers.
|
||||||
@ -462,18 +462,18 @@ xgb.cb.print.evaluation <- function(period = 1, showsd = TRUE) {
|
|||||||
xgb.cb.evaluation.log <- function() {
|
xgb.cb.evaluation.log <- function() {
|
||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "evaluation_log",
|
cb_name = "evaluation_log",
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
env$evaluation_log <- vector("list", end_iteration - begin_iteration + 1)
|
env$evaluation_log <- vector("list", end_iteration - begin_iteration + 1)
|
||||||
env$next_log <- 1
|
env$next_log <- 1
|
||||||
},
|
},
|
||||||
f_before_iter = NULL,
|
f_before_iter = NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
tmp <- .summarize.feval(iter_feval, TRUE)
|
tmp <- .summarize.feval(iter_feval, TRUE)
|
||||||
env$evaluation_log[[env$next_log]] <- list(iter = iteration, metrics = tmp$feval, sds = tmp$stdev)
|
env$evaluation_log[[env$next_log]] <- list(iter = iteration, metrics = tmp$feval, sds = tmp$stdev)
|
||||||
env$next_log <- env$next_log + 1
|
env$next_log <- env$next_log + 1
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
if (!NROW(env$evaluation_log)) {
|
if (!NROW(env$evaluation_log)) {
|
||||||
return(prev_cb_res)
|
return(prev_cb_res)
|
||||||
}
|
}
|
||||||
@ -543,7 +543,7 @@ xgb.cb.reset.parameters <- function(new_params) {
|
|||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "reset_parameters",
|
cb_name = "reset_parameters",
|
||||||
env = as.environment(list(new_params = new_params)),
|
env = as.environment(list(new_params = new_params)),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
env$end_iteration <- end_iteration
|
env$end_iteration <- end_iteration
|
||||||
|
|
||||||
pnames <- gsub(".", "_", names(env$new_params), fixed = TRUE)
|
pnames <- gsub(".", "_", names(env$new_params), fixed = TRUE)
|
||||||
@ -560,7 +560,7 @@ xgb.cb.reset.parameters <- function(new_params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
f_before_iter = function(env, model, data, watchlist, iteration) {
|
f_before_iter = function(env, model, data, evals, iteration) {
|
||||||
pars <- lapply(env$new_params, function(p) {
|
pars <- lapply(env$new_params, function(p) {
|
||||||
if (is.function(p)) {
|
if (is.function(p)) {
|
||||||
return(p(iteration, env$end_iteration))
|
return(p(iteration, env$end_iteration))
|
||||||
@ -589,9 +589,9 @@ xgb.cb.reset.parameters <- function(new_params) {
|
|||||||
#' @param maximize Whether to maximize the evaluation metric.
|
#' @param maximize Whether to maximize the evaluation metric.
|
||||||
#' @param metric_name The name of an evaluation column to use as a criteria for early
|
#' @param metric_name The name of an evaluation column to use as a criteria for early
|
||||||
#' stopping. If not set, the last column would be used.
|
#' stopping. If not set, the last column would be used.
|
||||||
#' Let's say the test data in \code{watchlist} was labelled as \code{dtest},
|
#' Let's say the test data in \code{evals} was labelled as \code{dtest},
|
||||||
#' and one wants to use the AUC in test data for early stopping regardless of where
|
#' and one wants to use the AUC in test data for early stopping regardless of where
|
||||||
#' it is in the \code{watchlist}, then one of the following would need to be set:
|
#' it is in the \code{evals}, then one of the following would need to be set:
|
||||||
#' \code{metric_name='dtest-auc'} or \code{metric_name='dtest_auc'}.
|
#' \code{metric_name='dtest-auc'} or \code{metric_name='dtest_auc'}.
|
||||||
#' All dash '-' characters in metric names are considered equivalent to '_'.
|
#' All dash '-' characters in metric names are considered equivalent to '_'.
|
||||||
#' @param verbose Whether to print the early stopping information.
|
#' @param verbose Whether to print the early stopping information.
|
||||||
@ -615,7 +615,7 @@ xgb.cb.reset.parameters <- function(new_params) {
|
|||||||
#' base-1 indexing, so it will be larger by '1' than the C-level 'best_iteration' that is accessed
|
#' base-1 indexing, so it will be larger by '1' than the C-level 'best_iteration' that is accessed
|
||||||
#' through \link{xgb.attr} or \link{xgb.attributes}.
|
#' through \link{xgb.attr} or \link{xgb.attributes}.
|
||||||
#'
|
#'
|
||||||
#' At least one data element is required in the evaluation watchlist for early stopping to work.
|
#' At least one dataset is required in `evals` for early stopping to work.
|
||||||
#' @export
|
#' @export
|
||||||
xgb.cb.early.stop <- function(
|
xgb.cb.early.stop <- function(
|
||||||
stopping_rounds,
|
stopping_rounds,
|
||||||
@ -642,15 +642,15 @@ xgb.cb.early.stop <- function(
|
|||||||
stopped_by_max_rounds = FALSE
|
stopped_by_max_rounds = FALSE
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
if (inherits(model, "xgb.Booster") && !length(watchlist)) {
|
if (inherits(model, "xgb.Booster") && !length(evals)) {
|
||||||
stop("For early stopping, watchlist must have at least one element")
|
stop("For early stopping, 'evals' must have at least one element")
|
||||||
}
|
}
|
||||||
env$begin_iteration <- begin_iteration
|
env$begin_iteration <- begin_iteration
|
||||||
return(NULL)
|
return(NULL)
|
||||||
},
|
},
|
||||||
f_before_iter = function(env, model, data, watchlist, iteration) NULL,
|
f_before_iter = function(env, model, data, evals, iteration) NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
sds <- NULL
|
sds <- NULL
|
||||||
if (NCOL(iter_feval) > 1) {
|
if (NCOL(iter_feval) > 1) {
|
||||||
tmp <- .summarize.feval(iter_feval, TRUE)
|
tmp <- .summarize.feval(iter_feval, TRUE)
|
||||||
@ -729,7 +729,7 @@ xgb.cb.early.stop <- function(
|
|||||||
}
|
}
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
if (inherits(model, "xgb.Booster") && !env$keep_all_iter && env$best_iteration < iteration) {
|
if (inherits(model, "xgb.Booster") && !env$keep_all_iter && env$best_iteration < iteration) {
|
||||||
# Note: it loses the attributes after being sliced,
|
# Note: it loses the attributes after being sliced,
|
||||||
# so they have to be re-assigned afterwards.
|
# so they have to be re-assigned afterwards.
|
||||||
@ -798,18 +798,18 @@ xgb.cb.save.model <- function(save_period = 0, save_name = "xgboost.ubj") {
|
|||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "save_model",
|
cb_name = "save_model",
|
||||||
env = as.environment(list(save_period = save_period, save_name = save_name, last_save = 0)),
|
env = as.environment(list(save_period = save_period, save_name = save_name, last_save = 0)),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
env$begin_iteration <- begin_iteration
|
env$begin_iteration <- begin_iteration
|
||||||
},
|
},
|
||||||
f_before_iter = NULL,
|
f_before_iter = NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
if (env$save_period > 0 && (iteration - env$begin_iteration) %% env$save_period == 0) {
|
if (env$save_period > 0 && (iteration - env$begin_iteration) %% env$save_period == 0) {
|
||||||
.save.model.w.formatted.name(model, env$save_name, iteration)
|
.save.model.w.formatted.name(model, env$save_name, iteration)
|
||||||
env$last_save <- iteration
|
env$last_save <- iteration
|
||||||
}
|
}
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
if (env$save_period == 0 && iteration > env$last_save) {
|
if (env$save_period == 0 && iteration > env$last_save) {
|
||||||
.save.model.w.formatted.name(model, env$save_name, iteration)
|
.save.model.w.formatted.name(model, env$save_name, iteration)
|
||||||
}
|
}
|
||||||
@ -840,19 +840,19 @@ xgb.cb.cv.predict <- function(save_models = FALSE, outputmargin = FALSE) {
|
|||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "cv_predict",
|
cb_name = "cv_predict",
|
||||||
env = as.environment(list(save_models = save_models, outputmargin = outputmargin)),
|
env = as.environment(list(save_models = save_models, outputmargin = outputmargin)),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
if (inherits(model, "xgb.Booster")) {
|
if (inherits(model, "xgb.Booster")) {
|
||||||
stop("'cv.predict' callback is only for 'xgb.cv'.")
|
stop("'cv.predict' callback is only for 'xgb.cv'.")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
f_before_iter = NULL,
|
f_before_iter = NULL,
|
||||||
f_after_iter = NULL,
|
f_after_iter = NULL,
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
pred <- NULL
|
pred <- NULL
|
||||||
for (fd in model) {
|
for (fd in model) {
|
||||||
pr <- predict(
|
pr <- predict(
|
||||||
fd$bst,
|
fd$bst,
|
||||||
fd$watchlist[[2L]],
|
fd$evals[[2L]],
|
||||||
outputmargin = env$outputmargin,
|
outputmargin = env$outputmargin,
|
||||||
reshape = TRUE
|
reshape = TRUE
|
||||||
)
|
)
|
||||||
@ -1002,7 +1002,7 @@ xgb.cb.gblinear.history <- function(sparse = FALSE) {
|
|||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "gblinear_history",
|
cb_name = "gblinear_history",
|
||||||
env = as.environment(list(sparse = sparse)),
|
env = as.environment(list(sparse = sparse)),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration, end_iteration) {
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration) {
|
||||||
if (!inherits(model, "xgb.Booster")) {
|
if (!inherits(model, "xgb.Booster")) {
|
||||||
model <- model[[1L]]$bst
|
model <- model[[1L]]$bst
|
||||||
}
|
}
|
||||||
@ -1013,7 +1013,7 @@ xgb.cb.gblinear.history <- function(sparse = FALSE) {
|
|||||||
env$next_idx <- 1
|
env$next_idx <- 1
|
||||||
},
|
},
|
||||||
f_before_iter = NULL,
|
f_before_iter = NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
if (inherits(model, "xgb.Booster")) {
|
if (inherits(model, "xgb.Booster")) {
|
||||||
coef_this <- .extract.coef(model, env$sparse)
|
coef_this <- .extract.coef(model, env$sparse)
|
||||||
} else {
|
} else {
|
||||||
@ -1023,7 +1023,7 @@ xgb.cb.gblinear.history <- function(sparse = FALSE) {
|
|||||||
env$next_idx <- env$next_idx + 1
|
env$next_idx <- env$next_idx + 1
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval, prev_cb_res) {
|
f_after_training = function(env, model, data, evals, iteration, final_feval, prev_cb_res) {
|
||||||
# in case of early stopping
|
# in case of early stopping
|
||||||
if (env$next_idx <= length(env$coef_hist)) {
|
if (env$next_idx <= length(env$coef_hist)) {
|
||||||
env$coef_hist <- head(env$coef_hist, env$next_idx - 1)
|
env$coef_hist <- head(env$coef_hist, env$next_idx - 1)
|
||||||
|
|||||||
@ -193,20 +193,20 @@ xgb.iter.update <- function(bst, dtrain, iter, obj) {
|
|||||||
# Evaluate one iteration.
|
# Evaluate one iteration.
|
||||||
# Returns a named vector of evaluation metrics
|
# Returns a named vector of evaluation metrics
|
||||||
# with the names in a 'datasetname-metricname' format.
|
# with the names in a 'datasetname-metricname' format.
|
||||||
xgb.iter.eval <- function(bst, watchlist, iter, feval) {
|
xgb.iter.eval <- function(bst, evals, iter, feval) {
|
||||||
handle <- xgb.get.handle(bst)
|
handle <- xgb.get.handle(bst)
|
||||||
|
|
||||||
if (length(watchlist) == 0)
|
if (length(evals) == 0)
|
||||||
return(NULL)
|
return(NULL)
|
||||||
|
|
||||||
evnames <- names(watchlist)
|
evnames <- names(evals)
|
||||||
if (is.null(feval)) {
|
if (is.null(feval)) {
|
||||||
msg <- .Call(XGBoosterEvalOneIter_R, handle, as.integer(iter), watchlist, as.list(evnames))
|
msg <- .Call(XGBoosterEvalOneIter_R, handle, as.integer(iter), evals, as.list(evnames))
|
||||||
mat <- matrix(strsplit(msg, '\\s+|:')[[1]][-1], nrow = 2)
|
mat <- matrix(strsplit(msg, '\\s+|:')[[1]][-1], nrow = 2)
|
||||||
res <- structure(as.numeric(mat[2, ]), names = mat[1, ])
|
res <- structure(as.numeric(mat[2, ]), names = mat[1, ])
|
||||||
} else {
|
} else {
|
||||||
res <- sapply(seq_along(watchlist), function(j) {
|
res <- sapply(seq_along(evals), function(j) {
|
||||||
w <- watchlist[[j]]
|
w <- evals[[j]]
|
||||||
## predict using all trees
|
## predict using all trees
|
||||||
preds <- predict(bst, w, outputmargin = TRUE, iterationrange = "all")
|
preds <- predict(bst, w, outputmargin = TRUE, iterationrange = "all")
|
||||||
eval_res <- feval(preds, w)
|
eval_res <- feval(preds, w)
|
||||||
|
|||||||
@ -71,7 +71,6 @@
|
|||||||
#' new.dtest <- xgb.DMatrix(
|
#' new.dtest <- xgb.DMatrix(
|
||||||
#' data = new.features.test, label = agaricus.test$label, nthread = 2
|
#' data = new.features.test, label = agaricus.test$label, nthread = 2
|
||||||
#' )
|
#' )
|
||||||
#' watchlist <- list(train = new.dtrain)
|
|
||||||
#' bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
#' bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||||
#'
|
#'
|
||||||
#' # Model accuracy with new features
|
#' # Model accuracy with new features
|
||||||
|
|||||||
@ -215,7 +215,7 @@ xgb.cv <- function(params = list(), data, nrounds, nfold, label = NULL, missing
|
|||||||
modelfile = NULL
|
modelfile = NULL
|
||||||
)
|
)
|
||||||
bst <- bst$bst
|
bst <- bst$bst
|
||||||
list(dtrain = dtrain, bst = bst, watchlist = list(train = dtrain, test = dtest), index = folds[[k]])
|
list(dtrain = dtrain, bst = bst, evals = list(train = dtrain, test = dtest), index = folds[[k]])
|
||||||
})
|
})
|
||||||
|
|
||||||
# extract parameters that can affect the relationship b/w #trees and #iterations
|
# extract parameters that can affect the relationship b/w #trees and #iterations
|
||||||
@ -254,7 +254,7 @@ xgb.cv <- function(params = list(), data, nrounds, nfold, label = NULL, missing
|
|||||||
)
|
)
|
||||||
xgb.iter.eval(
|
xgb.iter.eval(
|
||||||
bst = fd$bst,
|
bst = fd$bst,
|
||||||
watchlist = fd$watchlist,
|
evals = fd$evals,
|
||||||
iter = iteration - 1,
|
iter = iteration - 1,
|
||||||
feval = feval
|
feval = feval
|
||||||
)
|
)
|
||||||
|
|||||||
@ -114,13 +114,13 @@
|
|||||||
#' @param data training dataset. \code{xgb.train} accepts only an \code{xgb.DMatrix} as the input.
|
#' @param data training dataset. \code{xgb.train} accepts only an \code{xgb.DMatrix} as the input.
|
||||||
#' \code{xgboost}, in addition, also accepts \code{matrix}, \code{dgCMatrix}, or name of a local data file.
|
#' \code{xgboost}, in addition, also accepts \code{matrix}, \code{dgCMatrix}, or name of a local data file.
|
||||||
#' @param nrounds max number of boosting iterations.
|
#' @param nrounds max number of boosting iterations.
|
||||||
#' @param watchlist named list of xgb.DMatrix datasets to use for evaluating model performance.
|
#' @param evals Named list of `xgb.DMatrix` datasets to use for evaluating model performance.
|
||||||
#' Metrics specified in either \code{eval_metric} or \code{feval} will be computed for each
|
#' Metrics specified in either \code{eval_metric} or \code{feval} will be computed for each
|
||||||
#' of these datasets during each boosting iteration, and stored in the end as a field named
|
#' of these datasets during each boosting iteration, and stored in the end as a field named
|
||||||
#' \code{evaluation_log} in the resulting object. When either \code{verbose>=1} or
|
#' \code{evaluation_log} in the resulting object. When either \code{verbose>=1} or
|
||||||
#' \code{\link{xgb.cb.print.evaluation}} callback is engaged, the performance results are continuously
|
#' \code{\link{xgb.cb.print.evaluation}} callback is engaged, the performance results are continuously
|
||||||
#' printed out during the training.
|
#' printed out during the training.
|
||||||
#' E.g., specifying \code{watchlist=list(validation1=mat1, validation2=mat2)} allows to track
|
#' E.g., specifying \code{evals=list(validation1=mat1, validation2=mat2)} allows to track
|
||||||
#' the performance of each round's model on mat1 and mat2.
|
#' the performance of each round's model on mat1 and mat2.
|
||||||
#' @param obj customized objective function. Returns gradient and second order
|
#' @param obj customized objective function. Returns gradient and second order
|
||||||
#' gradient with given prediction and dtrain.
|
#' gradient with given prediction and dtrain.
|
||||||
@ -171,7 +171,7 @@
|
|||||||
#' @details
|
#' @details
|
||||||
#' These are the training functions for \code{xgboost}.
|
#' These are the training functions for \code{xgboost}.
|
||||||
#'
|
#'
|
||||||
#' The \code{xgb.train} interface supports advanced features such as \code{watchlist},
|
#' The \code{xgb.train} interface supports advanced features such as \code{evals},
|
||||||
#' customized objective and evaluation metric functions, therefore it is more flexible
|
#' customized objective and evaluation metric functions, therefore it is more flexible
|
||||||
#' than the \code{xgboost} interface.
|
#' than the \code{xgboost} interface.
|
||||||
#'
|
#'
|
||||||
@ -209,7 +209,7 @@
|
|||||||
#' \itemize{
|
#' \itemize{
|
||||||
#' \item \code{xgb.cb.print.evaluation} is turned on when \code{verbose > 0};
|
#' \item \code{xgb.cb.print.evaluation} is turned on when \code{verbose > 0};
|
||||||
#' and the \code{print_every_n} parameter is passed to it.
|
#' and the \code{print_every_n} parameter is passed to it.
|
||||||
#' \item \code{xgb.cb.evaluation.log} is on when \code{watchlist} is present.
|
#' \item \code{xgb.cb.evaluation.log} is on when \code{evals} is present.
|
||||||
#' \item \code{xgb.cb.early.stop}: when \code{early_stopping_rounds} is set.
|
#' \item \code{xgb.cb.early.stop}: when \code{early_stopping_rounds} is set.
|
||||||
#' \item \code{xgb.cb.save.model}: when \code{save_period > 0} is set.
|
#' \item \code{xgb.cb.save.model}: when \code{save_period > 0} is set.
|
||||||
#' }
|
#' }
|
||||||
@ -254,12 +254,12 @@
|
|||||||
#' dtest <- with(
|
#' dtest <- with(
|
||||||
#' agaricus.test, xgb.DMatrix(data, label = label, nthread = nthread)
|
#' agaricus.test, xgb.DMatrix(data, label = label, nthread = nthread)
|
||||||
#' )
|
#' )
|
||||||
#' watchlist <- list(train = dtrain, eval = dtest)
|
#' evals <- list(train = dtrain, eval = dtest)
|
||||||
#'
|
#'
|
||||||
#' ## A simple xgb.train example:
|
#' ## A simple xgb.train example:
|
||||||
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
#' objective = "binary:logistic", eval_metric = "auc")
|
#' objective = "binary:logistic", eval_metric = "auc")
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0)
|
#' bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0)
|
||||||
#'
|
#'
|
||||||
#' ## An xgb.train example where custom objective and evaluation metric are
|
#' ## An xgb.train example where custom objective and evaluation metric are
|
||||||
#' ## used:
|
#' ## used:
|
||||||
@ -280,15 +280,15 @@
|
|||||||
#' # as 'objective' and 'eval_metric' parameters in the params list:
|
#' # as 'objective' and 'eval_metric' parameters in the params list:
|
||||||
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
#' objective = logregobj, eval_metric = evalerror)
|
#' objective = logregobj, eval_metric = evalerror)
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0)
|
#' bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0)
|
||||||
#'
|
#'
|
||||||
#' # or through the ... arguments:
|
#' # or through the ... arguments:
|
||||||
#' param <- list(max_depth = 2, eta = 1, nthread = nthread)
|
#' param <- list(max_depth = 2, eta = 1, nthread = nthread)
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
#' bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
#' objective = logregobj, eval_metric = evalerror)
|
#' objective = logregobj, eval_metric = evalerror)
|
||||||
#'
|
#'
|
||||||
#' # or as dedicated 'obj' and 'feval' parameters of xgb.train:
|
#' # or as dedicated 'obj' and 'feval' parameters of xgb.train:
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 2, watchlist,
|
#' bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals,
|
||||||
#' obj = logregobj, feval = evalerror)
|
#' obj = logregobj, feval = evalerror)
|
||||||
#'
|
#'
|
||||||
#'
|
#'
|
||||||
@ -296,11 +296,11 @@
|
|||||||
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
#' param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
#' objective = "binary:logistic", eval_metric = "auc")
|
#' objective = "binary:logistic", eval_metric = "auc")
|
||||||
#' my_etas <- list(eta = c(0.5, 0.1))
|
#' my_etas <- list(eta = c(0.5, 0.1))
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
#' bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
#' callbacks = list(xgb.cb.reset.parameters(my_etas)))
|
#' callbacks = list(xgb.cb.reset.parameters(my_etas)))
|
||||||
#'
|
#'
|
||||||
#' ## Early stopping:
|
#' ## Early stopping:
|
||||||
#' bst <- xgb.train(param, dtrain, nrounds = 25, watchlist,
|
#' bst <- xgb.train(param, dtrain, nrounds = 25, evals = evals,
|
||||||
#' early_stopping_rounds = 3)
|
#' early_stopping_rounds = 3)
|
||||||
#'
|
#'
|
||||||
#' ## An 'xgboost' interface example:
|
#' ## An 'xgboost' interface example:
|
||||||
@ -311,7 +311,7 @@
|
|||||||
#'
|
#'
|
||||||
#' @rdname xgb.train
|
#' @rdname xgb.train
|
||||||
#' @export
|
#' @export
|
||||||
xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
xgb.train <- function(params = list(), data, nrounds, evals = list(),
|
||||||
obj = NULL, feval = NULL, verbose = 1, print_every_n = 1L,
|
obj = NULL, feval = NULL, verbose = 1, print_every_n = 1L,
|
||||||
early_stopping_rounds = NULL, maximize = NULL,
|
early_stopping_rounds = NULL, maximize = NULL,
|
||||||
save_period = NULL, save_name = "xgboost.model",
|
save_period = NULL, save_name = "xgboost.model",
|
||||||
@ -324,17 +324,17 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
check.custom.obj()
|
check.custom.obj()
|
||||||
check.custom.eval()
|
check.custom.eval()
|
||||||
|
|
||||||
# data & watchlist checks
|
# data & evals checks
|
||||||
dtrain <- data
|
dtrain <- data
|
||||||
if (!inherits(dtrain, "xgb.DMatrix"))
|
if (!inherits(dtrain, "xgb.DMatrix"))
|
||||||
stop("second argument dtrain must be xgb.DMatrix")
|
stop("second argument dtrain must be xgb.DMatrix")
|
||||||
if (length(watchlist) > 0) {
|
if (length(evals) > 0) {
|
||||||
if (typeof(watchlist) != "list" ||
|
if (typeof(evals) != "list" ||
|
||||||
!all(vapply(watchlist, inherits, logical(1), what = 'xgb.DMatrix')))
|
!all(vapply(evals, inherits, logical(1), what = 'xgb.DMatrix')))
|
||||||
stop("watchlist must be a list of xgb.DMatrix elements")
|
stop("'evals' must be a list of xgb.DMatrix elements")
|
||||||
evnames <- names(watchlist)
|
evnames <- names(evals)
|
||||||
if (is.null(evnames) || any(evnames == ""))
|
if (is.null(evnames) || any(evnames == ""))
|
||||||
stop("each element of the watchlist must have a name tag")
|
stop("each element of 'evals' must have a name tag")
|
||||||
}
|
}
|
||||||
# Handle multiple evaluation metrics given as a list
|
# Handle multiple evaluation metrics given as a list
|
||||||
for (m in params$eval_metric) {
|
for (m in params$eval_metric) {
|
||||||
@ -370,8 +370,8 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
if (verbose && !("print_evaluation" %in% cb_names)) {
|
if (verbose && !("print_evaluation" %in% cb_names)) {
|
||||||
callbacks <- add.callback(callbacks, xgb.cb.print.evaluation(print_every_n))
|
callbacks <- add.callback(callbacks, xgb.cb.print.evaluation(print_every_n))
|
||||||
}
|
}
|
||||||
# evaluation log callback: it is automatically enabled when watchlist is provided
|
# evaluation log callback: it is automatically enabled when 'evals' is provided
|
||||||
if (length(watchlist) && !("evaluation_log" %in% cb_names)) {
|
if (length(evals) && !("evaluation_log" %in% cb_names)) {
|
||||||
callbacks <- add.callback(callbacks, xgb.cb.evaluation.log())
|
callbacks <- add.callback(callbacks, xgb.cb.evaluation.log())
|
||||||
}
|
}
|
||||||
# Model saving callback
|
# Model saving callback
|
||||||
@ -385,7 +385,7 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
# Construct a booster (either a new one or load from xgb_model)
|
# Construct a booster (either a new one or load from xgb_model)
|
||||||
bst <- xgb.Booster(
|
bst <- xgb.Booster(
|
||||||
params = params,
|
params = params,
|
||||||
cachelist = append(watchlist, dtrain),
|
cachelist = append(evals, dtrain),
|
||||||
modelfile = xgb_model
|
modelfile = xgb_model
|
||||||
)
|
)
|
||||||
niter_init <- bst$niter
|
niter_init <- bst$niter
|
||||||
@ -407,7 +407,7 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
callbacks,
|
callbacks,
|
||||||
bst,
|
bst,
|
||||||
dtrain,
|
dtrain,
|
||||||
watchlist,
|
evals,
|
||||||
begin_iteration,
|
begin_iteration,
|
||||||
end_iteration
|
end_iteration
|
||||||
)
|
)
|
||||||
@ -419,7 +419,7 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
callbacks,
|
callbacks,
|
||||||
bst,
|
bst,
|
||||||
dtrain,
|
dtrain,
|
||||||
watchlist,
|
evals,
|
||||||
iteration
|
iteration
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -431,10 +431,10 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
)
|
)
|
||||||
|
|
||||||
bst_evaluation <- NULL
|
bst_evaluation <- NULL
|
||||||
if (length(watchlist) > 0) {
|
if (length(evals) > 0) {
|
||||||
bst_evaluation <- xgb.iter.eval(
|
bst_evaluation <- xgb.iter.eval(
|
||||||
bst = bst,
|
bst = bst,
|
||||||
watchlist = watchlist,
|
evals = evals,
|
||||||
iter = iteration - 1,
|
iter = iteration - 1,
|
||||||
feval = feval
|
feval = feval
|
||||||
)
|
)
|
||||||
@ -444,7 +444,7 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
callbacks,
|
callbacks,
|
||||||
bst,
|
bst,
|
||||||
dtrain,
|
dtrain,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
bst_evaluation
|
bst_evaluation
|
||||||
)
|
)
|
||||||
@ -456,7 +456,7 @@ xgb.train <- function(params = list(), data, nrounds, watchlist = list(),
|
|||||||
callbacks,
|
callbacks,
|
||||||
bst,
|
bst,
|
||||||
dtrain,
|
dtrain,
|
||||||
watchlist,
|
evals,
|
||||||
iteration,
|
iteration,
|
||||||
bst_evaluation
|
bst_evaluation
|
||||||
)
|
)
|
||||||
|
|||||||
@ -18,9 +18,9 @@ xgboost <- function(data = NULL, label = NULL, missing = NA, weight = NULL,
|
|||||||
nthread = merged$nthread
|
nthread = merged$nthread
|
||||||
)
|
)
|
||||||
|
|
||||||
watchlist <- list(train = dtrain)
|
evals <- list(train = dtrain)
|
||||||
|
|
||||||
bst <- xgb.train(params, dtrain, nrounds, watchlist, verbose = verbose, print_every_n = print_every_n,
|
bst <- xgb.train(params, dtrain, nrounds, evals, verbose = verbose, print_every_n = print_every_n,
|
||||||
early_stopping_rounds = early_stopping_rounds, maximize = maximize,
|
early_stopping_rounds = early_stopping_rounds, maximize = maximize,
|
||||||
save_period = save_period, save_name = save_name,
|
save_period = save_period, save_name = save_name,
|
||||||
xgb_model = xgb_model, callbacks = callbacks, ...)
|
xgb_model = xgb_model, callbacks = callbacks, ...)
|
||||||
|
|||||||
@ -74,17 +74,17 @@ print(paste("sum(abs(pred3-pred))=", sum(abs(pred3 - pred))))
|
|||||||
# to use advanced features, we need to put data in xgb.DMatrix
|
# to use advanced features, we need to put data in xgb.DMatrix
|
||||||
dtrain <- xgb.DMatrix(data = train$data, label = train$label)
|
dtrain <- xgb.DMatrix(data = train$data, label = train$label)
|
||||||
dtest <- xgb.DMatrix(data = test$data, label = test$label)
|
dtest <- xgb.DMatrix(data = test$data, label = test$label)
|
||||||
#---------------Using watchlist----------------
|
#---------------Using an evaluation set----------------
|
||||||
# watchlist is a list of xgb.DMatrix, each of them is tagged with name
|
# 'evals' is a list of xgb.DMatrix, each of them is tagged with name
|
||||||
watchlist <- list(train = dtrain, test = dtest)
|
evals <- list(train = dtrain, test = dtest)
|
||||||
# to train with watchlist, use xgb.train, which contains more advanced features
|
# to train with an evaluation set, use xgb.train, which contains more advanced features
|
||||||
# watchlist allows us to monitor the evaluation result on all data in the list
|
# 'evals' argument allows us to monitor the evaluation result on all data in the list
|
||||||
print("Train xgboost using xgb.train with watchlist")
|
print("Train xgboost using xgb.train with evaluation data")
|
||||||
bst <- xgb.train(data = dtrain, max_depth = 2, eta = 1, nrounds = 2, watchlist = watchlist,
|
bst <- xgb.train(data = dtrain, max_depth = 2, eta = 1, nrounds = 2, evals = evals,
|
||||||
nthread = 2, objective = "binary:logistic")
|
nthread = 2, objective = "binary:logistic")
|
||||||
# we can change evaluation metrics, or use multiple evaluation metrics
|
# we can change evaluation metrics, or use multiple evaluation metrics
|
||||||
print("train xgboost using xgb.train with watchlist, watch logloss and error")
|
print("train xgboost using xgb.train with evaluation data, watch logloss and error")
|
||||||
bst <- xgb.train(data = dtrain, max_depth = 2, eta = 1, nrounds = 2, watchlist = watchlist,
|
bst <- xgb.train(data = dtrain, max_depth = 2, eta = 1, nrounds = 2, evals = evals,
|
||||||
eval_metric = "error", eval_metric = "logloss",
|
eval_metric = "error", eval_metric = "logloss",
|
||||||
nthread = 2, objective = "binary:logistic")
|
nthread = 2, objective = "binary:logistic")
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ bst <- xgb.train(data = dtrain, max_depth = 2, eta = 1, nrounds = 2, watchlist =
|
|||||||
xgb.DMatrix.save(dtrain, "dtrain.buffer")
|
xgb.DMatrix.save(dtrain, "dtrain.buffer")
|
||||||
# to load it in, simply call xgb.DMatrix
|
# to load it in, simply call xgb.DMatrix
|
||||||
dtrain2 <- xgb.DMatrix("dtrain.buffer")
|
dtrain2 <- xgb.DMatrix("dtrain.buffer")
|
||||||
bst <- xgb.train(data = dtrain2, max_depth = 2, eta = 1, nrounds = 2, watchlist = watchlist,
|
bst <- xgb.train(data = dtrain2, max_depth = 2, eta = 1, nrounds = 2, evals = evals,
|
||||||
nthread = 2, objective = "binary:logistic")
|
nthread = 2, objective = "binary:logistic")
|
||||||
# information can be extracted from xgb.DMatrix using getinfo
|
# information can be extracted from xgb.DMatrix using getinfo
|
||||||
label <- getinfo(dtest, "label")
|
label <- getinfo(dtest, "label")
|
||||||
|
|||||||
@ -5,14 +5,14 @@ data(agaricus.test, package = 'xgboost')
|
|||||||
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
||||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
||||||
|
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
###
|
###
|
||||||
# advanced: start from a initial base prediction
|
# advanced: start from a initial base prediction
|
||||||
#
|
#
|
||||||
print('start running example to start from a initial prediction')
|
print('start running example to start from a initial prediction')
|
||||||
# train xgboost for 1 round
|
# train xgboost for 1 round
|
||||||
param <- list(max_depth = 2, eta = 1, nthread = 2, objective = 'binary:logistic')
|
param <- list(max_depth = 2, eta = 1, nthread = 2, objective = 'binary:logistic')
|
||||||
bst <- xgb.train(param, dtrain, 1, watchlist)
|
bst <- xgb.train(param, dtrain, 1, evals)
|
||||||
# Note: we need the margin value instead of transformed prediction in set_base_margin
|
# Note: we need the margin value instead of transformed prediction in set_base_margin
|
||||||
# do predict with output_margin=TRUE, will always give you margin values before logistic transformation
|
# do predict with output_margin=TRUE, will always give you margin values before logistic transformation
|
||||||
ptrain <- predict(bst, dtrain, outputmargin = TRUE)
|
ptrain <- predict(bst, dtrain, outputmargin = TRUE)
|
||||||
@ -23,4 +23,4 @@ setinfo(dtrain, "base_margin", ptrain)
|
|||||||
setinfo(dtest, "base_margin", ptest)
|
setinfo(dtest, "base_margin", ptest)
|
||||||
|
|
||||||
print('this is result of boost from initial prediction')
|
print('this is result of boost from initial prediction')
|
||||||
bst <- xgb.train(params = param, data = dtrain, nrounds = 1, watchlist = watchlist)
|
bst <- xgb.train(params = param, data = dtrain, nrounds = 1, evals = evals)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
|||||||
# note: for customized objective function, we leave objective as default
|
# note: for customized objective function, we leave objective as default
|
||||||
# note: what we are getting is margin value in prediction
|
# note: what we are getting is margin value in prediction
|
||||||
# you must know what you are doing
|
# you must know what you are doing
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
num_round <- 2
|
num_round <- 2
|
||||||
|
|
||||||
# user define objective function, given prediction, return gradient and second order gradient
|
# user define objective function, given prediction, return gradient and second order gradient
|
||||||
@ -38,7 +38,7 @@ param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0,
|
|||||||
print('start training with user customized objective')
|
print('start training with user customized objective')
|
||||||
# training with customized objective, we can also do step by step training
|
# training with customized objective, we can also do step by step training
|
||||||
# simply look at xgboost.py's implementation of train
|
# simply look at xgboost.py's implementation of train
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist)
|
bst <- xgb.train(param, dtrain, num_round, evals)
|
||||||
|
|
||||||
#
|
#
|
||||||
# there can be cases where you want additional information
|
# there can be cases where you want additional information
|
||||||
@ -62,4 +62,4 @@ param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0,
|
|||||||
print('start training with user customized objective, with additional attributes in DMatrix')
|
print('start training with user customized objective, with additional attributes in DMatrix')
|
||||||
# training with customized objective, we can also do step by step training
|
# training with customized objective, we can also do step by step training
|
||||||
# simply look at xgboost.py's implementation of train
|
# simply look at xgboost.py's implementation of train
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist)
|
bst <- xgb.train(param, dtrain, num_round, evals)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
|||||||
# note: what we are getting is margin value in prediction
|
# note: what we are getting is margin value in prediction
|
||||||
# you must know what you are doing
|
# you must know what you are doing
|
||||||
param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0)
|
param <- list(max_depth = 2, eta = 1, nthread = 2, verbosity = 0)
|
||||||
watchlist <- list(eval = dtest)
|
evals <- list(eval = dtest)
|
||||||
num_round <- 20
|
num_round <- 20
|
||||||
# user define objective function, given prediction, return gradient and second order gradient
|
# user define objective function, given prediction, return gradient and second order gradient
|
||||||
# this is log likelihood loss
|
# this is log likelihood loss
|
||||||
@ -32,7 +32,7 @@ evalerror <- function(preds, dtrain) {
|
|||||||
}
|
}
|
||||||
print('start training with early Stopping setting')
|
print('start training with early Stopping setting')
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist,
|
bst <- xgb.train(param, dtrain, num_round, evals,
|
||||||
objective = logregobj, eval_metric = evalerror, maximize = FALSE,
|
objective = logregobj, eval_metric = evalerror, maximize = FALSE,
|
||||||
early_stopping_round = 3)
|
early_stopping_round = 3)
|
||||||
bst <- xgb.cv(param, dtrain, num_round, nfold = 5,
|
bst <- xgb.cv(param, dtrain, num_round, nfold = 5,
|
||||||
|
|||||||
@ -25,9 +25,9 @@ param <- list(objective = "binary:logistic", booster = "gblinear",
|
|||||||
##
|
##
|
||||||
# the rest of settings are the same
|
# the rest of settings are the same
|
||||||
##
|
##
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
num_round <- 2
|
num_round <- 2
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist)
|
bst <- xgb.train(param, dtrain, num_round, evals)
|
||||||
ypred <- predict(bst, dtest)
|
ypred <- predict(bst, dtest)
|
||||||
labels <- getinfo(dtest, 'label')
|
labels <- getinfo(dtest, 'label')
|
||||||
cat('error of preds=', mean(as.numeric(ypred > 0.5) != labels), '\n')
|
cat('error of preds=', mean(as.numeric(ypred > 0.5) != labels), '\n')
|
||||||
|
|||||||
@ -23,7 +23,7 @@ y <- rbinom(N, 1, plogis(m))
|
|||||||
tr <- sample.int(N, N * 0.75)
|
tr <- sample.int(N, N * 0.75)
|
||||||
dtrain <- xgb.DMatrix(X[tr, ], label = y[tr])
|
dtrain <- xgb.DMatrix(X[tr, ], label = y[tr])
|
||||||
dtest <- xgb.DMatrix(X[-tr, ], label = y[-tr])
|
dtest <- xgb.DMatrix(X[-tr, ], label = y[-tr])
|
||||||
wl <- list(train = dtrain, test = dtest)
|
evals <- list(train = dtrain, test = dtest)
|
||||||
|
|
||||||
# An example of running 'gpu_hist' algorithm
|
# An example of running 'gpu_hist' algorithm
|
||||||
# which is
|
# which is
|
||||||
@ -35,11 +35,11 @@ wl <- list(train = dtrain, test = dtest)
|
|||||||
param <- list(objective = 'reg:logistic', eval_metric = 'auc', subsample = 0.5, nthread = 4,
|
param <- list(objective = 'reg:logistic', eval_metric = 'auc', subsample = 0.5, nthread = 4,
|
||||||
max_bin = 64, tree_method = 'gpu_hist')
|
max_bin = 64, tree_method = 'gpu_hist')
|
||||||
pt <- proc.time()
|
pt <- proc.time()
|
||||||
bst_gpu <- xgb.train(param, dtrain, watchlist = wl, nrounds = 50)
|
bst_gpu <- xgb.train(param, dtrain, evals = evals, nrounds = 50)
|
||||||
proc.time() - pt
|
proc.time() - pt
|
||||||
|
|
||||||
# Compare to the 'hist' algorithm:
|
# Compare to the 'hist' algorithm:
|
||||||
param$tree_method <- 'hist'
|
param$tree_method <- 'hist'
|
||||||
pt <- proc.time()
|
pt <- proc.time()
|
||||||
bst_hist <- xgb.train(param, dtrain, watchlist = wl, nrounds = 50)
|
bst_hist <- xgb.train(param, dtrain, evals = evals, nrounds = 50)
|
||||||
proc.time() - pt
|
proc.time() - pt
|
||||||
|
|||||||
@ -6,11 +6,11 @@ dtrain <- xgb.DMatrix(agaricus.train$data, label = agaricus.train$label)
|
|||||||
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
dtest <- xgb.DMatrix(agaricus.test$data, label = agaricus.test$label)
|
||||||
|
|
||||||
param <- list(max_depth = 2, eta = 1, objective = 'binary:logistic')
|
param <- list(max_depth = 2, eta = 1, objective = 'binary:logistic')
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
nrounds <- 2
|
nrounds <- 2
|
||||||
|
|
||||||
# training the model for two rounds
|
# training the model for two rounds
|
||||||
bst <- xgb.train(param, dtrain, nrounds, nthread = 2, watchlist)
|
bst <- xgb.train(param, dtrain, nrounds, nthread = 2, evals = evals)
|
||||||
cat('start testing prediction from first n trees\n')
|
cat('start testing prediction from first n trees\n')
|
||||||
labels <- getinfo(dtest, 'label')
|
labels <- getinfo(dtest, 'label')
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,6 @@ colnames(new.features.test) <- colnames(new.features.train)
|
|||||||
# learning with new features
|
# learning with new features
|
||||||
new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
new.dtrain <- xgb.DMatrix(data = new.features.train, label = agaricus.train$label)
|
||||||
new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
new.dtest <- xgb.DMatrix(data = new.features.test, label = agaricus.test$label)
|
||||||
watchlist <- list(train = new.dtrain)
|
|
||||||
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||||
|
|
||||||
# Model accuracy with new features
|
# Model accuracy with new features
|
||||||
|
|||||||
@ -39,7 +39,7 @@ bst <- xgb.train(
|
|||||||
data = d_train,
|
data = d_train,
|
||||||
params = params,
|
params = params,
|
||||||
maximize = FALSE,
|
maximize = FALSE,
|
||||||
watchlist = list(train = d_train),
|
evals = list(train = d_train),
|
||||||
nrounds = 20)
|
nrounds = 20)
|
||||||
|
|
||||||
var_imp <- xgb.importance(attr(x, 'Dimnames')[[2]], model = bst)
|
var_imp <- xgb.importance(attr(x, 'Dimnames')[[2]], model = bst)
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
xgb.Callback(
|
xgb.Callback(
|
||||||
cb_name = "custom_callback",
|
cb_name = "custom_callback",
|
||||||
env = new.env(),
|
env = new.env(),
|
||||||
f_before_training = function(env, model, data, watchlist, begin_iteration,
|
f_before_training = function(env, model, data, evals, begin_iteration, end_iteration)
|
||||||
end_iteration) NULL,
|
NULL,
|
||||||
f_before_iter = function(env, model, data, watchlist, iteration) NULL,
|
f_before_iter = function(env, model, data, evals, iteration) NULL,
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) NULL,
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) NULL,
|
||||||
f_after_training = function(env, model, data, watchlist, iteration, final_feval,
|
f_after_training = function(env, model, data, evals, iteration, final_feval,
|
||||||
prev_cb_res) NULL
|
prev_cb_res) NULL
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ not be kept after the model fitting function terminates (see parameter \code{f_a
|
|||||||
For \link{xgb.cv}, folds are a list with a structure as follows:\itemize{
|
For \link{xgb.cv}, folds are a list with a structure as follows:\itemize{
|
||||||
\item \code{dtrain}: The training data for the fold (as an \code{xgb.DMatrix} object).
|
\item \code{dtrain}: The training data for the fold (as an \code{xgb.DMatrix} object).
|
||||||
\item \code{bst}: Rhe \code{xgb.Booster} object for the fold.
|
\item \code{bst}: Rhe \code{xgb.Booster} object for the fold.
|
||||||
\item \code{watchlist}: A list with two DMatrices, with names \code{train} and \code{test}
|
\item \code{evals}: A list containing two DMatrices, with names \code{train} and \code{test}
|
||||||
(\code{test} is the held-out data for the fold).
|
(\code{test} is the held-out data for the fold).
|
||||||
\item \code{index}: The indices of the hold-out data for that fold (base-1 indexing),
|
\item \code{index}: The indices of the hold-out data for that fold (base-1 indexing),
|
||||||
from which the \code{test} entry in the watchlist was obtained.
|
from which the \code{test} entry in \code{evals} was obtained.
|
||||||
}
|
}
|
||||||
|
|
||||||
This object should \bold{not} be in-place modified in ways that conflict with the
|
This object should \bold{not} be in-place modified in ways that conflict with the
|
||||||
@ -104,7 +104,7 @@ For keeping variables across iterations, it's recommended to use \code{env} inst
|
|||||||
Note that, for \link{xgb.cv}, this will be the full data, while data for the specific
|
Note that, for \link{xgb.cv}, this will be the full data, while data for the specific
|
||||||
folds can be found in the \code{model} object.
|
folds can be found in the \code{model} object.
|
||||||
|
|
||||||
\item watchlist The evaluation watchlist, as passed under argument \code{watchlist} to
|
\item evals The evaluation data, as passed under argument \code{evals} to
|
||||||
\link{xgb.train}.
|
\link{xgb.train}.
|
||||||
|
|
||||||
For \link{xgb.cv}, this will always be \code{NULL}.
|
For \link{xgb.cv}, this will always be \code{NULL}.
|
||||||
@ -127,15 +127,15 @@ example by using the early stopping callback \link{xgb.cb.early.stop}.
|
|||||||
\item iteration Index of the iteration number that is being executed (first iteration
|
\item iteration Index of the iteration number that is being executed (first iteration
|
||||||
will be the same as parameter \code{begin_iteration}, then next one will add +1, and so on).
|
will be the same as parameter \code{begin_iteration}, then next one will add +1, and so on).
|
||||||
|
|
||||||
\item iter_feval Evaluation metrics for the \code{watchlist} that was supplied, either
|
\item iter_feval Evaluation metrics for \code{evals} that were supplied, either
|
||||||
determined by the objective, or by parameter \code{feval}.
|
determined by the objective, or by parameter \code{feval}.
|
||||||
|
|
||||||
For \link{xgb.train}, this will be a named vector with one entry per element in
|
For \link{xgb.train}, this will be a named vector with one entry per element in
|
||||||
\code{watchlist}, where the names are determined as 'watchlist name' + '-' + 'metric name' - for
|
\code{evals}, where the names are determined as 'evals name' + '-' + 'metric name' - for
|
||||||
example, if \code{watchlist} contains an entry named "tr" and the metric is "rmse",
|
example, if \code{evals} contains an entry named "tr" and the metric is "rmse",
|
||||||
this will be a one-element vector with name "tr-rmse".
|
this will be a one-element vector with name "tr-rmse".
|
||||||
|
|
||||||
For \link{xgb.cv}, this will be a 2d matrix with dimensions \verb{[length(watchlist), nfolds]},
|
For \link{xgb.cv}, this will be a 2d matrix with dimensions \verb{[length(evals), nfolds]},
|
||||||
where the row names will follow the same naming logic as the one-dimensional vector
|
where the row names will follow the same naming logic as the one-dimensional vector
|
||||||
that is passed in \link{xgb.train}.
|
that is passed in \link{xgb.train}.
|
||||||
|
|
||||||
@ -187,18 +187,18 @@ the order in which the callbacks are passed to the model fitting function.
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
# Example constructing a custom callback that calculates
|
# Example constructing a custom callback that calculates
|
||||||
# squared error on the training data, without a watchlist,
|
# squared error on the training data (no separate test set),
|
||||||
# and outputs the per-iteration results.
|
# and outputs the per-iteration results.
|
||||||
ssq_callback <- xgb.Callback(
|
ssq_callback <- xgb.Callback(
|
||||||
cb_name = "ssq",
|
cb_name = "ssq",
|
||||||
f_before_training = function(env, model, data, watchlist,
|
f_before_training = function(env, model, data, evals,
|
||||||
begin_iteration, end_iteration) {
|
begin_iteration, end_iteration) {
|
||||||
# A vector to keep track of a number at each iteration
|
# A vector to keep track of a number at each iteration
|
||||||
env$logs <- rep(NA_real_, end_iteration - begin_iteration + 1)
|
env$logs <- rep(NA_real_, end_iteration - begin_iteration + 1)
|
||||||
},
|
},
|
||||||
f_after_iter = function(env, model, data, watchlist, iteration, iter_feval) {
|
f_after_iter = function(env, model, data, evals, iteration, iter_feval) {
|
||||||
# This calculates the sum of squared errors on the training data.
|
# This calculates the sum of squared errors on the training data.
|
||||||
# Note that this can be better done by passing a 'watchlist' entry,
|
# Note that this can be better done by passing an 'evals' entry,
|
||||||
# but this demonstrates a way in which callbacks can be structured.
|
# but this demonstrates a way in which callbacks can be structured.
|
||||||
pred <- predict(model, data)
|
pred <- predict(model, data)
|
||||||
err <- pred - getinfo(data, "label")
|
err <- pred - getinfo(data, "label")
|
||||||
@ -214,7 +214,7 @@ ssq_callback <- xgb.Callback(
|
|||||||
# A return value of 'TRUE' here would signal to finalize the training
|
# A return value of 'TRUE' here would signal to finalize the training
|
||||||
return(FALSE)
|
return(FALSE)
|
||||||
},
|
},
|
||||||
f_after_training = function(env, model, data, watchlist, iteration,
|
f_after_training = function(env, model, data, evals, iteration,
|
||||||
final_feval, prev_cb_res) {
|
final_feval, prev_cb_res) {
|
||||||
return(env$logs)
|
return(env$logs)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,9 +20,9 @@ the evaluation metric in order to stop the training.}
|
|||||||
|
|
||||||
\item{metric_name}{The name of an evaluation column to use as a criteria for early
|
\item{metric_name}{The name of an evaluation column to use as a criteria for early
|
||||||
stopping. If not set, the last column would be used.
|
stopping. If not set, the last column would be used.
|
||||||
Let's say the test data in \code{watchlist} was labelled as \code{dtest},
|
Let's say the test data in \code{evals} was labelled as \code{dtest},
|
||||||
and one wants to use the AUC in test data for early stopping regardless of where
|
and one wants to use the AUC in test data for early stopping regardless of where
|
||||||
it is in the \code{watchlist}, then one of the following would need to be set:
|
it is in the \code{evals}, then one of the following would need to be set:
|
||||||
\code{metric_name='dtest-auc'} or \code{metric_name='dtest_auc'}.
|
\code{metric_name='dtest-auc'} or \code{metric_name='dtest_auc'}.
|
||||||
All dash '-' characters in metric names are considered equivalent to '_'.}
|
All dash '-' characters in metric names are considered equivalent to '_'.}
|
||||||
|
|
||||||
@ -51,5 +51,5 @@ condition occurred. Note that the \code{best_iteration} that is stored under R a
|
|||||||
base-1 indexing, so it will be larger by '1' than the C-level 'best_iteration' that is accessed
|
base-1 indexing, so it will be larger by '1' than the C-level 'best_iteration' that is accessed
|
||||||
through \link{xgb.attr} or \link{xgb.attributes}.
|
through \link{xgb.attr} or \link{xgb.attributes}.
|
||||||
|
|
||||||
At least one data element is required in the evaluation watchlist for early stopping to work.
|
At least one dataset is required in \code{evals} for early stopping to work.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Callback for logging the evaluation history
|
|||||||
}
|
}
|
||||||
\details{
|
\details{
|
||||||
This callback creates a table with per-iteration evaluation metrics (see parameters
|
This callback creates a table with per-iteration evaluation metrics (see parameters
|
||||||
\code{watchlist} and \code{feval} in \link{xgb.train}).
|
\code{evals} and \code{feval} in \link{xgb.train}).
|
||||||
|
|
||||||
Note: in the column names of the final data.table, the dash '-' character is replaced with
|
Note: in the column names of the final data.table, the dash '-' character is replaced with
|
||||||
the underscore '_' in order to make the column names more like regular R identifiers.
|
the underscore '_' in order to make the column names more like regular R identifiers.
|
||||||
|
|||||||
@ -82,7 +82,6 @@ new.dtrain <- xgb.DMatrix(
|
|||||||
new.dtest <- xgb.DMatrix(
|
new.dtest <- xgb.DMatrix(
|
||||||
data = new.features.test, label = agaricus.test$label, nthread = 2
|
data = new.features.test, label = agaricus.test$label, nthread = 2
|
||||||
)
|
)
|
||||||
watchlist <- list(train = new.dtrain)
|
|
||||||
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
bst <- xgb.train(params = param, data = new.dtrain, nrounds = nrounds, nthread = 2)
|
||||||
|
|
||||||
# Model accuracy with new features
|
# Model accuracy with new features
|
||||||
|
|||||||
@ -9,7 +9,7 @@ xgb.train(
|
|||||||
params = list(),
|
params = list(),
|
||||||
data,
|
data,
|
||||||
nrounds,
|
nrounds,
|
||||||
watchlist = list(),
|
evals = list(),
|
||||||
obj = NULL,
|
obj = NULL,
|
||||||
feval = NULL,
|
feval = NULL,
|
||||||
verbose = 1,
|
verbose = 1,
|
||||||
@ -158,13 +158,13 @@ List is provided in detail section.}
|
|||||||
|
|
||||||
\item{nrounds}{max number of boosting iterations.}
|
\item{nrounds}{max number of boosting iterations.}
|
||||||
|
|
||||||
\item{watchlist}{named list of xgb.DMatrix datasets to use for evaluating model performance.
|
\item{evals}{Named list of \code{xgb.DMatrix} datasets to use for evaluating model performance.
|
||||||
Metrics specified in either \code{eval_metric} or \code{feval} will be computed for each
|
Metrics specified in either \code{eval_metric} or \code{feval} will be computed for each
|
||||||
of these datasets during each boosting iteration, and stored in the end as a field named
|
of these datasets during each boosting iteration, and stored in the end as a field named
|
||||||
\code{evaluation_log} in the resulting object. When either \code{verbose>=1} or
|
\code{evaluation_log} in the resulting object. When either \code{verbose>=1} or
|
||||||
\code{\link{xgb.cb.print.evaluation}} callback is engaged, the performance results are continuously
|
\code{\link{xgb.cb.print.evaluation}} callback is engaged, the performance results are continuously
|
||||||
printed out during the training.
|
printed out during the training.
|
||||||
E.g., specifying \code{watchlist=list(validation1=mat1, validation2=mat2)} allows to track
|
E.g., specifying \code{evals=list(validation1=mat1, validation2=mat2)} allows to track
|
||||||
the performance of each round's model on mat1 and mat2.}
|
the performance of each round's model on mat1 and mat2.}
|
||||||
|
|
||||||
\item{obj}{customized objective function. Returns gradient and second order
|
\item{obj}{customized objective function. Returns gradient and second order
|
||||||
@ -234,7 +234,7 @@ The \code{xgboost} function is a simpler wrapper for \code{xgb.train}.
|
|||||||
\details{
|
\details{
|
||||||
These are the training functions for \code{xgboost}.
|
These are the training functions for \code{xgboost}.
|
||||||
|
|
||||||
The \code{xgb.train} interface supports advanced features such as \code{watchlist},
|
The \code{xgb.train} interface supports advanced features such as \code{evals},
|
||||||
customized objective and evaluation metric functions, therefore it is more flexible
|
customized objective and evaluation metric functions, therefore it is more flexible
|
||||||
than the \code{xgboost} interface.
|
than the \code{xgboost} interface.
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ The following callbacks are automatically created when certain parameters are se
|
|||||||
\itemize{
|
\itemize{
|
||||||
\item \code{xgb.cb.print.evaluation} is turned on when \code{verbose > 0};
|
\item \code{xgb.cb.print.evaluation} is turned on when \code{verbose > 0};
|
||||||
and the \code{print_every_n} parameter is passed to it.
|
and the \code{print_every_n} parameter is passed to it.
|
||||||
\item \code{xgb.cb.evaluation.log} is on when \code{watchlist} is present.
|
\item \code{xgb.cb.evaluation.log} is on when \code{evals} is present.
|
||||||
\item \code{xgb.cb.early.stop}: when \code{early_stopping_rounds} is set.
|
\item \code{xgb.cb.early.stop}: when \code{early_stopping_rounds} is set.
|
||||||
\item \code{xgb.cb.save.model}: when \code{save_period > 0} is set.
|
\item \code{xgb.cb.save.model}: when \code{save_period > 0} is set.
|
||||||
}
|
}
|
||||||
@ -307,12 +307,12 @@ dtrain <- with(
|
|||||||
dtest <- with(
|
dtest <- with(
|
||||||
agaricus.test, xgb.DMatrix(data, label = label, nthread = nthread)
|
agaricus.test, xgb.DMatrix(data, label = label, nthread = nthread)
|
||||||
)
|
)
|
||||||
watchlist <- list(train = dtrain, eval = dtest)
|
evals <- list(train = dtrain, eval = dtest)
|
||||||
|
|
||||||
## A simple xgb.train example:
|
## A simple xgb.train example:
|
||||||
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
objective = "binary:logistic", eval_metric = "auc")
|
objective = "binary:logistic", eval_metric = "auc")
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0)
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0)
|
||||||
|
|
||||||
## An xgb.train example where custom objective and evaluation metric are
|
## An xgb.train example where custom objective and evaluation metric are
|
||||||
## used:
|
## used:
|
||||||
@ -333,15 +333,15 @@ evalerror <- function(preds, dtrain) {
|
|||||||
# as 'objective' and 'eval_metric' parameters in the params list:
|
# as 'objective' and 'eval_metric' parameters in the params list:
|
||||||
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
objective = logregobj, eval_metric = evalerror)
|
objective = logregobj, eval_metric = evalerror)
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0)
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0)
|
||||||
|
|
||||||
# or through the ... arguments:
|
# or through the ... arguments:
|
||||||
param <- list(max_depth = 2, eta = 1, nthread = nthread)
|
param <- list(max_depth = 2, eta = 1, nthread = nthread)
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
objective = logregobj, eval_metric = evalerror)
|
objective = logregobj, eval_metric = evalerror)
|
||||||
|
|
||||||
# or as dedicated 'obj' and 'feval' parameters of xgb.train:
|
# or as dedicated 'obj' and 'feval' parameters of xgb.train:
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist,
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals,
|
||||||
obj = logregobj, feval = evalerror)
|
obj = logregobj, feval = evalerror)
|
||||||
|
|
||||||
|
|
||||||
@ -349,11 +349,11 @@ bst <- xgb.train(param, dtrain, nrounds = 2, watchlist,
|
|||||||
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
param <- list(max_depth = 2, eta = 1, nthread = nthread,
|
||||||
objective = "binary:logistic", eval_metric = "auc")
|
objective = "binary:logistic", eval_metric = "auc")
|
||||||
my_etas <- list(eta = c(0.5, 0.1))
|
my_etas <- list(eta = c(0.5, 0.1))
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_etas)))
|
callbacks = list(xgb.cb.reset.parameters(my_etas)))
|
||||||
|
|
||||||
## Early stopping:
|
## Early stopping:
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 25, watchlist,
|
bst <- xgb.train(param, dtrain, nrounds = 25, evals = evals,
|
||||||
early_stopping_rounds = 3)
|
early_stopping_rounds = 3)
|
||||||
|
|
||||||
## An 'xgboost' interface example:
|
## An 'xgboost' interface example:
|
||||||
|
|||||||
@ -20,7 +20,7 @@ test_that("train and predict binary classification", {
|
|||||||
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
||||||
eta = 1, nthread = n_threads, nrounds = nrounds,
|
eta = 1, nthread = n_threads, nrounds = nrounds,
|
||||||
objective = "binary:logistic", eval_metric = "error",
|
objective = "binary:logistic", eval_metric = "error",
|
||||||
watchlist = list(train = xgb.DMatrix(train$data, label = train$label))
|
evals = list(train = xgb.DMatrix(train$data, label = train$label))
|
||||||
),
|
),
|
||||||
"train-error"
|
"train-error"
|
||||||
)
|
)
|
||||||
@ -152,7 +152,7 @@ test_that("train and predict softprob", {
|
|||||||
data = xgb.DMatrix(as.matrix(iris[, -5]), label = lb),
|
data = xgb.DMatrix(as.matrix(iris[, -5]), label = lb),
|
||||||
max_depth = 3, eta = 0.5, nthread = n_threads, nrounds = 5,
|
max_depth = 3, eta = 0.5, nthread = n_threads, nrounds = 5,
|
||||||
objective = "multi:softprob", num_class = 3, eval_metric = "merror",
|
objective = "multi:softprob", num_class = 3, eval_metric = "merror",
|
||||||
watchlist = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
evals = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
||||||
),
|
),
|
||||||
"train-merror"
|
"train-merror"
|
||||||
)
|
)
|
||||||
@ -203,7 +203,7 @@ test_that("train and predict softmax", {
|
|||||||
data = xgb.DMatrix(as.matrix(iris[, -5]), label = lb),
|
data = xgb.DMatrix(as.matrix(iris[, -5]), label = lb),
|
||||||
max_depth = 3, eta = 0.5, nthread = n_threads, nrounds = 5,
|
max_depth = 3, eta = 0.5, nthread = n_threads, nrounds = 5,
|
||||||
objective = "multi:softmax", num_class = 3, eval_metric = "merror",
|
objective = "multi:softmax", num_class = 3, eval_metric = "merror",
|
||||||
watchlist = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
evals = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
||||||
),
|
),
|
||||||
"train-merror"
|
"train-merror"
|
||||||
)
|
)
|
||||||
@ -226,7 +226,7 @@ test_that("train and predict RF", {
|
|||||||
nthread = n_threads,
|
nthread = n_threads,
|
||||||
nrounds = 1, objective = "binary:logistic", eval_metric = "error",
|
nrounds = 1, objective = "binary:logistic", eval_metric = "error",
|
||||||
num_parallel_tree = 20, subsample = 0.6, colsample_bytree = 0.1,
|
num_parallel_tree = 20, subsample = 0.6, colsample_bytree = 0.1,
|
||||||
watchlist = list(train = xgb.DMatrix(train$data, label = lb))
|
evals = list(train = xgb.DMatrix(train$data, label = lb))
|
||||||
)
|
)
|
||||||
expect_equal(xgb.get.num.boosted.rounds(bst), 1)
|
expect_equal(xgb.get.num.boosted.rounds(bst), 1)
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ test_that("train and predict RF with softprob", {
|
|||||||
objective = "multi:softprob", eval_metric = "merror",
|
objective = "multi:softprob", eval_metric = "merror",
|
||||||
num_class = 3, verbose = 0,
|
num_class = 3, verbose = 0,
|
||||||
num_parallel_tree = 4, subsample = 0.5, colsample_bytree = 0.5,
|
num_parallel_tree = 4, subsample = 0.5, colsample_bytree = 0.5,
|
||||||
watchlist = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
evals = list(train = xgb.DMatrix(as.matrix(iris[, -5]), label = lb))
|
||||||
)
|
)
|
||||||
expect_equal(xgb.get.num.boosted.rounds(bst), 15)
|
expect_equal(xgb.get.num.boosted.rounds(bst), 15)
|
||||||
# predict for all iterations:
|
# predict for all iterations:
|
||||||
@ -271,7 +271,7 @@ test_that("use of multiple eval metrics works", {
|
|||||||
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
||||||
eta = 1, nthread = n_threads, nrounds = 2, objective = "binary:logistic",
|
eta = 1, nthread = n_threads, nrounds = 2, objective = "binary:logistic",
|
||||||
eval_metric = "error", eval_metric = "auc", eval_metric = "logloss",
|
eval_metric = "error", eval_metric = "auc", eval_metric = "logloss",
|
||||||
watchlist = list(train = xgb.DMatrix(train$data, label = train$label))
|
evals = list(train = xgb.DMatrix(train$data, label = train$label))
|
||||||
),
|
),
|
||||||
"train-error.*train-auc.*train-logloss"
|
"train-error.*train-auc.*train-logloss"
|
||||||
)
|
)
|
||||||
@ -283,7 +283,7 @@ test_that("use of multiple eval metrics works", {
|
|||||||
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
data = xgb.DMatrix(train$data, label = train$label), max_depth = 2,
|
||||||
eta = 1, nthread = n_threads, nrounds = 2, objective = "binary:logistic",
|
eta = 1, nthread = n_threads, nrounds = 2, objective = "binary:logistic",
|
||||||
eval_metric = list("error", "auc", "logloss"),
|
eval_metric = list("error", "auc", "logloss"),
|
||||||
watchlist = list(train = xgb.DMatrix(train$data, label = train$label))
|
evals = list(train = xgb.DMatrix(train$data, label = train$label))
|
||||||
),
|
),
|
||||||
"train-error.*train-auc.*train-logloss"
|
"train-error.*train-auc.*train-logloss"
|
||||||
)
|
)
|
||||||
@ -295,19 +295,19 @@ test_that("use of multiple eval metrics works", {
|
|||||||
|
|
||||||
test_that("training continuation works", {
|
test_that("training continuation works", {
|
||||||
dtrain <- xgb.DMatrix(train$data, label = train$label, nthread = n_threads)
|
dtrain <- xgb.DMatrix(train$data, label = train$label, nthread = n_threads)
|
||||||
watchlist <- list(train = dtrain)
|
evals <- list(train = dtrain)
|
||||||
param <- list(
|
param <- list(
|
||||||
objective = "binary:logistic", max_depth = 2, eta = 1, nthread = n_threads
|
objective = "binary:logistic", max_depth = 2, eta = 1, nthread = n_threads
|
||||||
)
|
)
|
||||||
|
|
||||||
# for the reference, use 4 iterations at once:
|
# for the reference, use 4 iterations at once:
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 4, watchlist, verbose = 0)
|
bst <- xgb.train(param, dtrain, nrounds = 4, evals = evals, verbose = 0)
|
||||||
# first two iterations:
|
# first two iterations:
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst1 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0)
|
bst1 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0)
|
||||||
# continue for two more:
|
# continue for two more:
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0, xgb_model = bst1)
|
bst2 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0, xgb_model = bst1)
|
||||||
if (!windows_flag && !solaris_flag) {
|
if (!windows_flag && !solaris_flag) {
|
||||||
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ test_that("training continuation works", {
|
|||||||
expect_equal(dim(attributes(bst2)$evaluation_log), c(4, 2))
|
expect_equal(dim(attributes(bst2)$evaluation_log), c(4, 2))
|
||||||
expect_equal(attributes(bst2)$evaluation_log, attributes(bst)$evaluation_log)
|
expect_equal(attributes(bst2)$evaluation_log, attributes(bst)$evaluation_log)
|
||||||
# test continuing from raw model data
|
# test continuing from raw model data
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0, xgb_model = xgb.save.raw(bst1))
|
bst2 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0, xgb_model = xgb.save.raw(bst1))
|
||||||
if (!windows_flag && !solaris_flag) {
|
if (!windows_flag && !solaris_flag) {
|
||||||
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ test_that("training continuation works", {
|
|||||||
# test continuing from a model in file
|
# test continuing from a model in file
|
||||||
fname <- file.path(tempdir(), "xgboost.json")
|
fname <- file.path(tempdir(), "xgboost.json")
|
||||||
xgb.save(bst1, fname)
|
xgb.save(bst1, fname)
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0, xgb_model = fname)
|
bst2 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0, xgb_model = fname)
|
||||||
if (!windows_flag && !solaris_flag) {
|
if (!windows_flag && !solaris_flag) {
|
||||||
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
expect_equal(xgb.save.raw(bst), xgb.save.raw(bst2))
|
||||||
}
|
}
|
||||||
@ -417,7 +417,7 @@ test_that("max_delta_step works", {
|
|||||||
dtrain <- xgb.DMatrix(
|
dtrain <- xgb.DMatrix(
|
||||||
agaricus.train$data, label = agaricus.train$label, nthread = n_threads
|
agaricus.train$data, label = agaricus.train$label, nthread = n_threads
|
||||||
)
|
)
|
||||||
watchlist <- list(train = dtrain)
|
evals <- list(train = dtrain)
|
||||||
param <- list(
|
param <- list(
|
||||||
objective = "binary:logistic", eval_metric = "logloss", max_depth = 2,
|
objective = "binary:logistic", eval_metric = "logloss", max_depth = 2,
|
||||||
nthread = n_threads,
|
nthread = n_threads,
|
||||||
@ -425,9 +425,9 @@ test_that("max_delta_step works", {
|
|||||||
)
|
)
|
||||||
nrounds <- 5
|
nrounds <- 5
|
||||||
# model with no restriction on max_delta_step
|
# model with no restriction on max_delta_step
|
||||||
bst1 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1)
|
bst1 <- xgb.train(param, dtrain, nrounds, evals = evals, verbose = 1)
|
||||||
# model with restricted max_delta_step
|
# model with restricted max_delta_step
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds, watchlist, verbose = 1, max_delta_step = 1)
|
bst2 <- xgb.train(param, dtrain, nrounds, evals = evals, verbose = 1, max_delta_step = 1)
|
||||||
# the no-restriction model is expected to have consistently lower loss during the initial iterations
|
# the no-restriction model is expected to have consistently lower loss during the initial iterations
|
||||||
expect_true(all(attributes(bst1)$evaluation_log$train_logloss < attributes(bst2)$evaluation_log$train_logloss))
|
expect_true(all(attributes(bst1)$evaluation_log$train_logloss < attributes(bst2)$evaluation_log$train_logloss))
|
||||||
expect_lt(mean(attributes(bst1)$evaluation_log$train_logloss) / mean(attributes(bst2)$evaluation_log$train_logloss), 0.8)
|
expect_lt(mean(attributes(bst1)$evaluation_log$train_logloss) / mean(attributes(bst2)$evaluation_log$train_logloss), 0.8)
|
||||||
@ -444,7 +444,7 @@ test_that("colsample_bytree works", {
|
|||||||
colnames(test_x) <- paste0("Feature_", sprintf("%03d", 1:100))
|
colnames(test_x) <- paste0("Feature_", sprintf("%03d", 1:100))
|
||||||
dtrain <- xgb.DMatrix(train_x, label = train_y, nthread = n_threads)
|
dtrain <- xgb.DMatrix(train_x, label = train_y, nthread = n_threads)
|
||||||
dtest <- xgb.DMatrix(test_x, label = test_y, nthread = n_threads)
|
dtest <- xgb.DMatrix(test_x, label = test_y, nthread = n_threads)
|
||||||
watchlist <- list(train = dtrain, eval = dtest)
|
evals <- list(train = dtrain, eval = dtest)
|
||||||
## Use colsample_bytree = 0.01, so that roughly one out of 100 features is chosen for
|
## Use colsample_bytree = 0.01, so that roughly one out of 100 features is chosen for
|
||||||
## each tree
|
## each tree
|
||||||
param <- list(
|
param <- list(
|
||||||
@ -453,7 +453,7 @@ test_that("colsample_bytree works", {
|
|||||||
eval_metric = "auc"
|
eval_metric = "auc"
|
||||||
)
|
)
|
||||||
set.seed(2)
|
set.seed(2)
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 100, watchlist, verbose = 0)
|
bst <- xgb.train(param, dtrain, nrounds = 100, evals = evals, verbose = 0)
|
||||||
xgb.importance(model = bst)
|
xgb.importance(model = bst)
|
||||||
# If colsample_bytree works properly, a variety of features should be used
|
# If colsample_bytree works properly, a variety of features should be used
|
||||||
# in the 100 trees
|
# in the 100 trees
|
||||||
|
|||||||
@ -19,7 +19,7 @@ ltrain <- add.noise(train$label, 0.2)
|
|||||||
ltest <- add.noise(test$label, 0.2)
|
ltest <- add.noise(test$label, 0.2)
|
||||||
dtrain <- xgb.DMatrix(train$data, label = ltrain, nthread = n_threads)
|
dtrain <- xgb.DMatrix(train$data, label = ltrain, nthread = n_threads)
|
||||||
dtest <- xgb.DMatrix(test$data, label = ltest, nthread = n_threads)
|
dtest <- xgb.DMatrix(test$data, label = ltest, nthread = n_threads)
|
||||||
watchlist <- list(train = dtrain, test = dtest)
|
evals <- list(train = dtrain, test = dtest)
|
||||||
|
|
||||||
|
|
||||||
err <- function(label, pr) sum((pr > 0.5) != label) / length(label)
|
err <- function(label, pr) sum((pr > 0.5) != label) / length(label)
|
||||||
@ -39,7 +39,7 @@ test_that("xgb.cb.print.evaluation works as expected for xgb.train", {
|
|||||||
nthread = n_threads
|
nthread = n_threads
|
||||||
),
|
),
|
||||||
nrounds = 10,
|
nrounds = 10,
|
||||||
watchlist = list(train = dtrain, test = dtest),
|
evals = list(train = dtrain, test = dtest),
|
||||||
callbacks = list(xgb.cb.print.evaluation(period = 1))
|
callbacks = list(xgb.cb.print.evaluation(period = 1))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -57,7 +57,7 @@ test_that("xgb.cb.print.evaluation works as expected for xgb.train", {
|
|||||||
nthread = n_threads
|
nthread = n_threads
|
||||||
),
|
),
|
||||||
nrounds = 10,
|
nrounds = 10,
|
||||||
watchlist = list(train = dtrain, test = dtest),
|
evals = list(train = dtrain, test = dtest),
|
||||||
callbacks = list(xgb.cb.print.evaluation(period = 2))
|
callbacks = list(xgb.cb.print.evaluation(period = 2))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -117,7 +117,7 @@ test_that("xgb.cb.evaluation.log works as expected for xgb.train", {
|
|||||||
),
|
),
|
||||||
nrounds = 10,
|
nrounds = 10,
|
||||||
verbose = FALSE,
|
verbose = FALSE,
|
||||||
watchlist = list(train = dtrain, test = dtest),
|
evals = list(train = dtrain, test = dtest),
|
||||||
callbacks = list(xgb.cb.evaluation.log())
|
callbacks = list(xgb.cb.evaluation.log())
|
||||||
)
|
)
|
||||||
logs <- attributes(model)$evaluation_log
|
logs <- attributes(model)$evaluation_log
|
||||||
@ -155,7 +155,7 @@ param <- list(objective = "binary:logistic", eval_metric = "error",
|
|||||||
|
|
||||||
test_that("can store evaluation_log without printing", {
|
test_that("can store evaluation_log without printing", {
|
||||||
expect_silent(
|
expect_silent(
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 10, watchlist, eta = 1, verbose = 0)
|
bst <- xgb.train(param, dtrain, nrounds = 10, evals = evals, eta = 1, verbose = 0)
|
||||||
)
|
)
|
||||||
expect_false(is.null(attributes(bst)$evaluation_log))
|
expect_false(is.null(attributes(bst)$evaluation_log))
|
||||||
expect_false(is.null(attributes(bst)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bst)$evaluation_log$train_error))
|
||||||
@ -166,14 +166,14 @@ test_that("xgb.cb.reset.parameters works as expected", {
|
|||||||
|
|
||||||
# fixed eta
|
# fixed eta
|
||||||
set.seed(111)
|
set.seed(111)
|
||||||
bst0 <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 0.9, verbose = 0)
|
bst0 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, eta = 0.9, verbose = 0)
|
||||||
expect_false(is.null(attributes(bst0)$evaluation_log))
|
expect_false(is.null(attributes(bst0)$evaluation_log))
|
||||||
expect_false(is.null(attributes(bst0)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bst0)$evaluation_log$train_error))
|
||||||
|
|
||||||
# same eta but re-set as a vector parameter in the callback
|
# same eta but re-set as a vector parameter in the callback
|
||||||
set.seed(111)
|
set.seed(111)
|
||||||
my_par <- list(eta = c(0.9, 0.9))
|
my_par <- list(eta = c(0.9, 0.9))
|
||||||
bst1 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst1 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
||||||
expect_false(is.null(attributes(bst1)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bst1)$evaluation_log$train_error))
|
||||||
expect_equal(attributes(bst0)$evaluation_log$train_error,
|
expect_equal(attributes(bst0)$evaluation_log$train_error,
|
||||||
@ -182,7 +182,7 @@ test_that("xgb.cb.reset.parameters works as expected", {
|
|||||||
# same eta but re-set via a function in the callback
|
# same eta but re-set via a function in the callback
|
||||||
set.seed(111)
|
set.seed(111)
|
||||||
my_par <- list(eta = function(itr, itr_end) 0.9)
|
my_par <- list(eta = function(itr, itr_end) 0.9)
|
||||||
bst2 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst2 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
||||||
expect_false(is.null(attributes(bst2)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bst2)$evaluation_log$train_error))
|
||||||
expect_equal(attributes(bst0)$evaluation_log$train_error,
|
expect_equal(attributes(bst0)$evaluation_log$train_error,
|
||||||
@ -191,7 +191,7 @@ test_that("xgb.cb.reset.parameters works as expected", {
|
|||||||
# different eta re-set as a vector parameter in the callback
|
# different eta re-set as a vector parameter in the callback
|
||||||
set.seed(111)
|
set.seed(111)
|
||||||
my_par <- list(eta = c(0.6, 0.5))
|
my_par <- list(eta = c(0.6, 0.5))
|
||||||
bst3 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst3 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
||||||
expect_false(is.null(attributes(bst3)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bst3)$evaluation_log$train_error))
|
||||||
expect_false(all(attributes(bst0)$evaluation_log$train_error == attributes(bst3)$evaluation_log$train_error))
|
expect_false(all(attributes(bst0)$evaluation_log$train_error == attributes(bst3)$evaluation_log$train_error))
|
||||||
@ -199,7 +199,7 @@ test_that("xgb.cb.reset.parameters works as expected", {
|
|||||||
# resetting multiple parameters at the same time runs with no error
|
# resetting multiple parameters at the same time runs with no error
|
||||||
my_par <- list(eta = c(1., 0.5), gamma = c(1, 2), max_depth = c(4, 8))
|
my_par <- list(eta = c(1., 0.5), gamma = c(1, 2), max_depth = c(4, 8))
|
||||||
expect_error(
|
expect_error(
|
||||||
bst4 <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bst4 <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
||||||
, NA) # NA = no error
|
, NA) # NA = no error
|
||||||
# CV works as well
|
# CV works as well
|
||||||
@ -210,7 +210,7 @@ test_that("xgb.cb.reset.parameters works as expected", {
|
|||||||
|
|
||||||
# expect no learning with 0 learning rate
|
# expect no learning with 0 learning rate
|
||||||
my_par <- list(eta = c(0., 0.))
|
my_par <- list(eta = c(0., 0.))
|
||||||
bstX <- xgb.train(param, dtrain, nrounds = 2, watchlist, verbose = 0,
|
bstX <- xgb.train(param, dtrain, nrounds = 2, evals = evals, verbose = 0,
|
||||||
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
callbacks = list(xgb.cb.reset.parameters(my_par)))
|
||||||
expect_false(is.null(attributes(bstX)$evaluation_log$train_error))
|
expect_false(is.null(attributes(bstX)$evaluation_log$train_error))
|
||||||
er <- unique(attributes(bstX)$evaluation_log$train_error)
|
er <- unique(attributes(bstX)$evaluation_log$train_error)
|
||||||
@ -223,7 +223,7 @@ test_that("xgb.cb.save.model works as expected", {
|
|||||||
files <- unname(sapply(files, function(f) file.path(tempdir(), f)))
|
files <- unname(sapply(files, function(f) file.path(tempdir(), f)))
|
||||||
for (f in files) if (file.exists(f)) file.remove(f)
|
for (f in files) if (file.exists(f)) file.remove(f)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, eta = 1, verbose = 0,
|
||||||
save_period = 1, save_name = file.path(tempdir(), "xgboost_%02d.json"))
|
save_period = 1, save_name = file.path(tempdir(), "xgboost_%02d.json"))
|
||||||
expect_true(file.exists(files[1]))
|
expect_true(file.exists(files[1]))
|
||||||
expect_true(file.exists(files[2]))
|
expect_true(file.exists(files[2]))
|
||||||
@ -239,7 +239,7 @@ test_that("xgb.cb.save.model works as expected", {
|
|||||||
expect_equal(xgb.save.raw(bst), xgb.save.raw(b2))
|
expect_equal(xgb.save.raw(bst), xgb.save.raw(b2))
|
||||||
|
|
||||||
# save_period = 0 saves the last iteration's model
|
# save_period = 0 saves the last iteration's model
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 2, watchlist, eta = 1, verbose = 0,
|
bst <- xgb.train(param, dtrain, nrounds = 2, evals = evals, eta = 1, verbose = 0,
|
||||||
save_period = 0, save_name = file.path(tempdir(), 'xgboost.json'))
|
save_period = 0, save_name = file.path(tempdir(), 'xgboost.json'))
|
||||||
expect_true(file.exists(files[3]))
|
expect_true(file.exists(files[3]))
|
||||||
b2 <- xgb.load(files[3])
|
b2 <- xgb.load(files[3])
|
||||||
@ -252,7 +252,7 @@ test_that("xgb.cb.save.model works as expected", {
|
|||||||
test_that("early stopping xgb.train works", {
|
test_that("early stopping xgb.train works", {
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgb.train(param, dtrain, nrounds = 20, watchlist, eta = 0.3,
|
bst <- xgb.train(param, dtrain, nrounds = 20, evals = evals, eta = 0.3,
|
||||||
early_stopping_rounds = 3, maximize = FALSE)
|
early_stopping_rounds = 3, maximize = FALSE)
|
||||||
, "Stopping. Best iteration")
|
, "Stopping. Best iteration")
|
||||||
expect_false(is.null(xgb.attr(bst, "best_iteration")))
|
expect_false(is.null(xgb.attr(bst, "best_iteration")))
|
||||||
@ -266,7 +266,7 @@ test_that("early stopping xgb.train works", {
|
|||||||
|
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
expect_silent(
|
expect_silent(
|
||||||
bst0 <- xgb.train(param, dtrain, nrounds = 20, watchlist, eta = 0.3,
|
bst0 <- xgb.train(param, dtrain, nrounds = 20, evals = evals, eta = 0.3,
|
||||||
early_stopping_rounds = 3, maximize = FALSE, verbose = 0)
|
early_stopping_rounds = 3, maximize = FALSE, verbose = 0)
|
||||||
)
|
)
|
||||||
expect_equal(attributes(bst)$evaluation_log, attributes(bst0)$evaluation_log)
|
expect_equal(attributes(bst)$evaluation_log, attributes(bst0)$evaluation_log)
|
||||||
@ -282,7 +282,7 @@ test_that("early stopping xgb.train works", {
|
|||||||
test_that("early stopping using a specific metric works", {
|
test_that("early stopping using a specific metric works", {
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
expect_output(
|
expect_output(
|
||||||
bst <- xgb.train(param[-2], dtrain, nrounds = 20, watchlist, eta = 0.6,
|
bst <- xgb.train(param[-2], dtrain, nrounds = 20, evals = evals, eta = 0.6,
|
||||||
eval_metric = "logloss", eval_metric = "auc",
|
eval_metric = "logloss", eval_metric = "auc",
|
||||||
callbacks = list(xgb.cb.early.stop(stopping_rounds = 3, maximize = FALSE,
|
callbacks = list(xgb.cb.early.stop(stopping_rounds = 3, maximize = FALSE,
|
||||||
metric_name = 'test_logloss')))
|
metric_name = 'test_logloss')))
|
||||||
@ -315,7 +315,7 @@ test_that("early stopping works with titanic", {
|
|||||||
nrounds = 100,
|
nrounds = 100,
|
||||||
early_stopping_rounds = 3,
|
early_stopping_rounds = 3,
|
||||||
nthread = n_threads,
|
nthread = n_threads,
|
||||||
watchlist = list(train = xgb.DMatrix(dtx, label = dty))
|
evals = list(train = xgb.DMatrix(dtx, label = dty))
|
||||||
)
|
)
|
||||||
|
|
||||||
expect_true(TRUE) # should not crash
|
expect_true(TRUE) # should not crash
|
||||||
|
|||||||
@ -12,7 +12,7 @@ dtrain <- xgb.DMatrix(
|
|||||||
dtest <- xgb.DMatrix(
|
dtest <- xgb.DMatrix(
|
||||||
agaricus.test$data, label = agaricus.test$label, nthread = n_threads
|
agaricus.test$data, label = agaricus.test$label, nthread = n_threads
|
||||||
)
|
)
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
|
|
||||||
logregobj <- function(preds, dtrain) {
|
logregobj <- function(preds, dtrain) {
|
||||||
labels <- getinfo(dtrain, "label")
|
labels <- getinfo(dtrain, "label")
|
||||||
@ -33,7 +33,7 @@ param <- list(max_depth = 2, eta = 1, nthread = n_threads,
|
|||||||
num_round <- 2
|
num_round <- 2
|
||||||
|
|
||||||
test_that("custom objective works", {
|
test_that("custom objective works", {
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist)
|
bst <- xgb.train(param, dtrain, num_round, evals)
|
||||||
expect_equal(class(bst), "xgb.Booster")
|
expect_equal(class(bst), "xgb.Booster")
|
||||||
expect_false(is.null(attributes(bst)$evaluation_log))
|
expect_false(is.null(attributes(bst)$evaluation_log))
|
||||||
expect_false(is.null(attributes(bst)$evaluation_log$eval_error))
|
expect_false(is.null(attributes(bst)$evaluation_log$eval_error))
|
||||||
@ -48,7 +48,7 @@ test_that("custom objective in CV works", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test_that("custom objective with early stop works", {
|
test_that("custom objective with early stop works", {
|
||||||
bst <- xgb.train(param, dtrain, 10, watchlist)
|
bst <- xgb.train(param, dtrain, 10, evals)
|
||||||
expect_equal(class(bst), "xgb.Booster")
|
expect_equal(class(bst), "xgb.Booster")
|
||||||
train_log <- attributes(bst)$evaluation_log$train_error
|
train_log <- attributes(bst)$evaluation_log$train_error
|
||||||
expect_true(all(diff(train_log) <= 0))
|
expect_true(all(diff(train_log) <= 0))
|
||||||
@ -66,7 +66,7 @@ test_that("custom objective using DMatrix attr works", {
|
|||||||
return(list(grad = grad, hess = hess))
|
return(list(grad = grad, hess = hess))
|
||||||
}
|
}
|
||||||
param$objective <- logregobjattr
|
param$objective <- logregobjattr
|
||||||
bst <- xgb.train(param, dtrain, num_round, watchlist)
|
bst <- xgb.train(param, dtrain, num_round, evals)
|
||||||
expect_equal(class(bst), "xgb.Booster")
|
expect_equal(class(bst), "xgb.Booster")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -41,13 +41,13 @@ test_that("xgb.DMatrix: basic construction", {
|
|||||||
|
|
||||||
params <- list(tree_method = "hist", nthread = n_threads)
|
params <- list(tree_method = "hist", nthread = n_threads)
|
||||||
bst_fd <- xgb.train(
|
bst_fd <- xgb.train(
|
||||||
params, nrounds = 8, fd, watchlist = list(train = fd)
|
params, nrounds = 8, fd, evals = list(train = fd)
|
||||||
)
|
)
|
||||||
bst_dgr <- xgb.train(
|
bst_dgr <- xgb.train(
|
||||||
params, nrounds = 8, fdgr, watchlist = list(train = fdgr)
|
params, nrounds = 8, fdgr, evals = list(train = fdgr)
|
||||||
)
|
)
|
||||||
bst_dgc <- xgb.train(
|
bst_dgc <- xgb.train(
|
||||||
params, nrounds = 8, fdgc, watchlist = list(train = fdgc)
|
params, nrounds = 8, fdgc, evals = list(train = fdgc)
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_fd <- xgb.save.raw(bst_fd, raw_format = "ubj")
|
raw_fd <- xgb.save.raw(bst_fd, raw_format = "ubj")
|
||||||
|
|||||||
@ -14,19 +14,19 @@ test_that("gblinear works", {
|
|||||||
|
|
||||||
param <- list(objective = "binary:logistic", eval_metric = "error", booster = "gblinear",
|
param <- list(objective = "binary:logistic", eval_metric = "error", booster = "gblinear",
|
||||||
nthread = n_threads, eta = 0.8, alpha = 0.0001, lambda = 0.0001)
|
nthread = n_threads, eta = 0.8, alpha = 0.0001, lambda = 0.0001)
|
||||||
watchlist <- list(eval = dtest, train = dtrain)
|
evals <- list(eval = dtest, train = dtrain)
|
||||||
|
|
||||||
n <- 5 # iterations
|
n <- 5 # iterations
|
||||||
ERR_UL <- 0.005 # upper limit for the test set error
|
ERR_UL <- 0.005 # upper limit for the test set error
|
||||||
VERB <- 0 # chatterbox switch
|
VERB <- 0 # chatterbox switch
|
||||||
|
|
||||||
param$updater <- 'shotgun'
|
param$updater <- 'shotgun'
|
||||||
bst <- xgb.train(param, dtrain, n, watchlist, verbose = VERB, feature_selector = 'shuffle')
|
bst <- xgb.train(param, dtrain, n, evals, verbose = VERB, feature_selector = 'shuffle')
|
||||||
ypred <- predict(bst, dtest)
|
ypred <- predict(bst, dtest)
|
||||||
expect_equal(length(getinfo(dtest, 'label')), 1611)
|
expect_equal(length(getinfo(dtest, 'label')), 1611)
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, n, watchlist, verbose = VERB, feature_selector = 'cyclic',
|
bst <- xgb.train(param, dtrain, n, evals, verbose = VERB, feature_selector = 'cyclic',
|
||||||
callbacks = list(xgb.cb.gblinear.history()))
|
callbacks = list(xgb.cb.gblinear.history()))
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
||||||
h <- xgb.gblinear.history(bst)
|
h <- xgb.gblinear.history(bst)
|
||||||
@ -34,16 +34,16 @@ test_that("gblinear works", {
|
|||||||
expect_is(h, "matrix")
|
expect_is(h, "matrix")
|
||||||
|
|
||||||
param$updater <- 'coord_descent'
|
param$updater <- 'coord_descent'
|
||||||
bst <- xgb.train(param, dtrain, n, watchlist, verbose = VERB, feature_selector = 'cyclic')
|
bst <- xgb.train(param, dtrain, n, evals, verbose = VERB, feature_selector = 'cyclic')
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, n, watchlist, verbose = VERB, feature_selector = 'shuffle')
|
bst <- xgb.train(param, dtrain, n, evals, verbose = VERB, feature_selector = 'shuffle')
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, 2, watchlist, verbose = VERB, feature_selector = 'greedy')
|
bst <- xgb.train(param, dtrain, 2, evals, verbose = VERB, feature_selector = 'greedy')
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[2], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[2], ERR_UL)
|
||||||
|
|
||||||
bst <- xgb.train(param, dtrain, n, watchlist, verbose = VERB, feature_selector = 'thrifty',
|
bst <- xgb.train(param, dtrain, n, evals, verbose = VERB, feature_selector = 'thrifty',
|
||||||
top_k = 50, callbacks = list(xgb.cb.gblinear.history(sparse = TRUE)))
|
top_k = 50, callbacks = list(xgb.cb.gblinear.history(sparse = TRUE)))
|
||||||
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
expect_lt(attributes(bst)$evaluation_log$eval_error[n], ERR_UL)
|
||||||
h <- xgb.gblinear.history(bst)
|
h <- xgb.gblinear.history(bst)
|
||||||
|
|||||||
@ -15,7 +15,7 @@ test_that('Test ranking with unweighted data', {
|
|||||||
|
|
||||||
params <- list(eta = 1, tree_method = 'exact', objective = 'rank:pairwise', max_depth = 1,
|
params <- list(eta = 1, tree_method = 'exact', objective = 'rank:pairwise', max_depth = 1,
|
||||||
eval_metric = 'auc', eval_metric = 'aucpr', nthread = n_threads)
|
eval_metric = 'auc', eval_metric = 'aucpr', nthread = n_threads)
|
||||||
bst <- xgb.train(params, dtrain, nrounds = 10, watchlist = list(train = dtrain))
|
bst <- xgb.train(params, dtrain, nrounds = 10, evals = list(train = dtrain))
|
||||||
# Check if the metric is monotone increasing
|
# Check if the metric is monotone increasing
|
||||||
expect_true(all(diff(attributes(bst)$evaluation_log$train_auc) >= 0))
|
expect_true(all(diff(attributes(bst)$evaluation_log$train_auc) >= 0))
|
||||||
expect_true(all(diff(attributes(bst)$evaluation_log$train_aucpr) >= 0))
|
expect_true(all(diff(attributes(bst)$evaluation_log$train_aucpr) >= 0))
|
||||||
@ -39,7 +39,7 @@ test_that('Test ranking with weighted data', {
|
|||||||
eta = 1, tree_method = "exact", objective = "rank:pairwise", max_depth = 1,
|
eta = 1, tree_method = "exact", objective = "rank:pairwise", max_depth = 1,
|
||||||
eval_metric = "auc", eval_metric = "aucpr", nthread = n_threads
|
eval_metric = "auc", eval_metric = "aucpr", nthread = n_threads
|
||||||
)
|
)
|
||||||
bst <- xgb.train(params, dtrain, nrounds = 10, watchlist = list(train = dtrain))
|
bst <- xgb.train(params, dtrain, nrounds = 10, evals = list(train = dtrain))
|
||||||
# Check if the metric is monotone increasing
|
# Check if the metric is monotone increasing
|
||||||
expect_true(all(diff(attributes(bst)$evaluation_log$train_auc) >= 0))
|
expect_true(all(diff(attributes(bst)$evaluation_log$train_auc) >= 0))
|
||||||
expect_true(all(diff(attributes(bst)$evaluation_log$train_aucpr) >= 0))
|
expect_true(all(diff(attributes(bst)$evaluation_log$train_aucpr) >= 0))
|
||||||
|
|||||||
@ -17,7 +17,7 @@ dtest <- xgb.DMatrix(
|
|||||||
win32_flag <- .Platform$OS.type == "windows" && .Machine$sizeof.pointer != 8
|
win32_flag <- .Platform$OS.type == "windows" && .Machine$sizeof.pointer != 8
|
||||||
|
|
||||||
test_that("updating the model works", {
|
test_that("updating the model works", {
|
||||||
watchlist <- list(train = dtrain, test = dtest)
|
evals <- list(train = dtrain, test = dtest)
|
||||||
|
|
||||||
# no-subsampling
|
# no-subsampling
|
||||||
p1 <- list(
|
p1 <- list(
|
||||||
@ -25,19 +25,19 @@ test_that("updating the model works", {
|
|||||||
updater = "grow_colmaker,prune"
|
updater = "grow_colmaker,prune"
|
||||||
)
|
)
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst1 <- xgb.train(p1, dtrain, nrounds = 10, watchlist, verbose = 0)
|
bst1 <- xgb.train(p1, dtrain, nrounds = 10, evals = evals, verbose = 0)
|
||||||
tr1 <- xgb.model.dt.tree(model = bst1)
|
tr1 <- xgb.model.dt.tree(model = bst1)
|
||||||
|
|
||||||
# with subsampling
|
# with subsampling
|
||||||
p2 <- modifyList(p1, list(subsample = 0.1))
|
p2 <- modifyList(p1, list(subsample = 0.1))
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst2 <- xgb.train(p2, dtrain, nrounds = 10, watchlist, verbose = 0)
|
bst2 <- xgb.train(p2, dtrain, nrounds = 10, evals = evals, verbose = 0)
|
||||||
tr2 <- xgb.model.dt.tree(model = bst2)
|
tr2 <- xgb.model.dt.tree(model = bst2)
|
||||||
|
|
||||||
# the same no-subsampling boosting with an extra 'refresh' updater:
|
# the same no-subsampling boosting with an extra 'refresh' updater:
|
||||||
p1r <- modifyList(p1, list(updater = 'grow_colmaker,prune,refresh', refresh_leaf = FALSE))
|
p1r <- modifyList(p1, list(updater = 'grow_colmaker,prune,refresh', refresh_leaf = FALSE))
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst1r <- xgb.train(p1r, dtrain, nrounds = 10, watchlist, verbose = 0)
|
bst1r <- xgb.train(p1r, dtrain, nrounds = 10, evals = evals, verbose = 0)
|
||||||
tr1r <- xgb.model.dt.tree(model = bst1r)
|
tr1r <- xgb.model.dt.tree(model = bst1r)
|
||||||
# all should be the same when no subsampling
|
# all should be the same when no subsampling
|
||||||
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1r)$evaluation_log)
|
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1r)$evaluation_log)
|
||||||
@ -53,7 +53,7 @@ test_that("updating the model works", {
|
|||||||
# the same boosting with subsampling with an extra 'refresh' updater:
|
# the same boosting with subsampling with an extra 'refresh' updater:
|
||||||
p2r <- modifyList(p2, list(updater = 'grow_colmaker,prune,refresh', refresh_leaf = FALSE))
|
p2r <- modifyList(p2, list(updater = 'grow_colmaker,prune,refresh', refresh_leaf = FALSE))
|
||||||
set.seed(11)
|
set.seed(11)
|
||||||
bst2r <- xgb.train(p2r, dtrain, nrounds = 10, watchlist, verbose = 0)
|
bst2r <- xgb.train(p2r, dtrain, nrounds = 10, evals = evals, verbose = 0)
|
||||||
tr2r <- xgb.model.dt.tree(model = bst2r)
|
tr2r <- xgb.model.dt.tree(model = bst2r)
|
||||||
# should be the same evaluation but different gains and larger cover
|
# should be the same evaluation but different gains and larger cover
|
||||||
expect_equal(attributes(bst2)$evaluation_log, attributes(bst2r)$evaluation_log)
|
expect_equal(attributes(bst2)$evaluation_log, attributes(bst2r)$evaluation_log)
|
||||||
@ -66,7 +66,7 @@ test_that("updating the model works", {
|
|||||||
# process type 'update' for no-subsampling model, refreshing the tree stats AND leaves from training data:
|
# process type 'update' for no-subsampling model, refreshing the tree stats AND leaves from training data:
|
||||||
set.seed(123)
|
set.seed(123)
|
||||||
p1u <- modifyList(p1, list(process_type = 'update', updater = 'refresh', refresh_leaf = TRUE))
|
p1u <- modifyList(p1, list(process_type = 'update', updater = 'refresh', refresh_leaf = TRUE))
|
||||||
bst1u <- xgb.train(p1u, dtrain, nrounds = 10, watchlist, verbose = 0, xgb_model = bst1)
|
bst1u <- xgb.train(p1u, dtrain, nrounds = 10, evals = evals, verbose = 0, xgb_model = bst1)
|
||||||
tr1u <- xgb.model.dt.tree(model = bst1u)
|
tr1u <- xgb.model.dt.tree(model = bst1u)
|
||||||
# all should be the same when no subsampling
|
# all should be the same when no subsampling
|
||||||
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1u)$evaluation_log)
|
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1u)$evaluation_log)
|
||||||
@ -79,7 +79,7 @@ test_that("updating the model works", {
|
|||||||
|
|
||||||
# same thing but with a serialized model
|
# same thing but with a serialized model
|
||||||
set.seed(123)
|
set.seed(123)
|
||||||
bst1u <- xgb.train(p1u, dtrain, nrounds = 10, watchlist, verbose = 0, xgb_model = xgb.save.raw(bst1))
|
bst1u <- xgb.train(p1u, dtrain, nrounds = 10, evals = evals, verbose = 0, xgb_model = xgb.save.raw(bst1))
|
||||||
tr1u <- xgb.model.dt.tree(model = bst1u)
|
tr1u <- xgb.model.dt.tree(model = bst1u)
|
||||||
# all should be the same when no subsampling
|
# all should be the same when no subsampling
|
||||||
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1u)$evaluation_log)
|
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1u)$evaluation_log)
|
||||||
@ -87,7 +87,7 @@ test_that("updating the model works", {
|
|||||||
|
|
||||||
# process type 'update' for model with subsampling, refreshing only the tree stats from training data:
|
# process type 'update' for model with subsampling, refreshing only the tree stats from training data:
|
||||||
p2u <- modifyList(p2, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
p2u <- modifyList(p2, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
||||||
bst2u <- xgb.train(p2u, dtrain, nrounds = 10, watchlist, verbose = 0, xgb_model = bst2)
|
bst2u <- xgb.train(p2u, dtrain, nrounds = 10, evals = evals, verbose = 0, xgb_model = bst2)
|
||||||
tr2u <- xgb.model.dt.tree(model = bst2u)
|
tr2u <- xgb.model.dt.tree(model = bst2u)
|
||||||
# should be the same evaluation but different gains and larger cover
|
# should be the same evaluation but different gains and larger cover
|
||||||
expect_equal(attributes(bst2)$evaluation_log, attributes(bst2u)$evaluation_log)
|
expect_equal(attributes(bst2)$evaluation_log, attributes(bst2u)$evaluation_log)
|
||||||
@ -102,7 +102,7 @@ test_that("updating the model works", {
|
|||||||
|
|
||||||
# process type 'update' for no-subsampling model, refreshing only the tree stats from TEST data:
|
# process type 'update' for no-subsampling model, refreshing only the tree stats from TEST data:
|
||||||
p1ut <- modifyList(p1, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
p1ut <- modifyList(p1, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
||||||
bst1ut <- xgb.train(p1ut, dtest, nrounds = 10, watchlist, verbose = 0, xgb_model = bst1)
|
bst1ut <- xgb.train(p1ut, dtest, nrounds = 10, evals = evals, verbose = 0, xgb_model = bst1)
|
||||||
tr1ut <- xgb.model.dt.tree(model = bst1ut)
|
tr1ut <- xgb.model.dt.tree(model = bst1ut)
|
||||||
# should be the same evaluations but different gains and smaller cover (test data is smaller)
|
# should be the same evaluations but different gains and smaller cover (test data is smaller)
|
||||||
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1ut)$evaluation_log)
|
expect_equal(attributes(bst1)$evaluation_log, attributes(bst1ut)$evaluation_log)
|
||||||
@ -115,18 +115,18 @@ test_that("updating works for multiclass & multitree", {
|
|||||||
dtr <- xgb.DMatrix(
|
dtr <- xgb.DMatrix(
|
||||||
as.matrix(iris[, -5]), label = as.numeric(iris$Species) - 1, nthread = n_threads
|
as.matrix(iris[, -5]), label = as.numeric(iris$Species) - 1, nthread = n_threads
|
||||||
)
|
)
|
||||||
watchlist <- list(train = dtr)
|
evals <- list(train = dtr)
|
||||||
p0 <- list(max_depth = 2, eta = 0.5, nthread = n_threads, subsample = 0.6,
|
p0 <- list(max_depth = 2, eta = 0.5, nthread = n_threads, subsample = 0.6,
|
||||||
objective = "multi:softprob", num_class = 3, num_parallel_tree = 2,
|
objective = "multi:softprob", num_class = 3, num_parallel_tree = 2,
|
||||||
base_score = 0)
|
base_score = 0)
|
||||||
set.seed(121)
|
set.seed(121)
|
||||||
bst0 <- xgb.train(p0, dtr, 5, watchlist, verbose = 0)
|
bst0 <- xgb.train(p0, dtr, 5, evals = evals, verbose = 0)
|
||||||
tr0 <- xgb.model.dt.tree(model = bst0)
|
tr0 <- xgb.model.dt.tree(model = bst0)
|
||||||
|
|
||||||
# run update process for an original model with subsampling
|
# run update process for an original model with subsampling
|
||||||
p0u <- modifyList(p0, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
p0u <- modifyList(p0, list(process_type = 'update', updater = 'refresh', refresh_leaf = FALSE))
|
||||||
bst0u <- xgb.train(p0u, dtr, nrounds = xgb.get.num.boosted.rounds(bst0),
|
bst0u <- xgb.train(p0u, dtr, nrounds = xgb.get.num.boosted.rounds(bst0),
|
||||||
watchlist, xgb_model = bst0, verbose = 0)
|
evals = evals, xgb_model = bst0, verbose = 0)
|
||||||
tr0u <- xgb.model.dt.tree(model = bst0u)
|
tr0u <- xgb.model.dt.tree(model = bst0u)
|
||||||
|
|
||||||
# should be the same evaluation but different gains and larger cover
|
# should be the same evaluation but different gains and larger cover
|
||||||
|
|||||||
@ -341,10 +341,10 @@ One way to measure progress in learning of a model is to provide to **XGBoost**
|
|||||||
|
|
||||||
> in some way it is similar to what we have done above with the average error. The main difference is that below it was after building the model, and now it is during the construction that we measure errors.
|
> in some way it is similar to what we have done above with the average error. The main difference is that below it was after building the model, and now it is during the construction that we measure errors.
|
||||||
|
|
||||||
For the purpose of this example, we use `watchlist` parameter. It is a list of `xgb.DMatrix`, each of them tagged with a name.
|
For the purpose of this example, we use the `evals` parameter. It is a list of `xgb.DMatrix` objects, each of them tagged with a name.
|
||||||
|
|
||||||
```{r watchlist, message=F, warning=F}
|
```{r evals, message=F, warning=F}
|
||||||
watchlist <- list(train = dtrain, test = dtest)
|
evals <- list(train = dtrain, test = dtest)
|
||||||
|
|
||||||
bst <- xgb.train(
|
bst <- xgb.train(
|
||||||
data = dtrain
|
data = dtrain
|
||||||
@ -355,7 +355,7 @@ bst <- xgb.train(
|
|||||||
, objective = "binary:logistic"
|
, objective = "binary:logistic"
|
||||||
)
|
)
|
||||||
, nrounds = 2
|
, nrounds = 2
|
||||||
, watchlist = watchlist
|
, evals = evals
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ If with your own dataset you have not such results, you should think about how y
|
|||||||
|
|
||||||
For a better understanding of the learning progression, you may want to have some specific metric or even use multiple evaluation metrics.
|
For a better understanding of the learning progression, you may want to have some specific metric or even use multiple evaluation metrics.
|
||||||
|
|
||||||
```{r watchlist2, message=F, warning=F}
|
```{r evals2, message=F, warning=F}
|
||||||
bst <- xgb.train(
|
bst <- xgb.train(
|
||||||
data = dtrain
|
data = dtrain
|
||||||
, max_depth = 2
|
, max_depth = 2
|
||||||
@ -379,7 +379,7 @@ bst <- xgb.train(
|
|||||||
, eval_metric = "logloss"
|
, eval_metric = "logloss"
|
||||||
)
|
)
|
||||||
, nrounds = 2
|
, nrounds = 2
|
||||||
, watchlist = watchlist
|
, evals = evals
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ bst <- xgb.train(
|
|||||||
, eval_metric = "logloss"
|
, eval_metric = "logloss"
|
||||||
)
|
)
|
||||||
, nrounds = 2
|
, nrounds = 2
|
||||||
, watchlist = watchlist
|
, evals = evals
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -430,7 +430,7 @@ bst <- xgb.train(
|
|||||||
, objective = "binary:logistic"
|
, objective = "binary:logistic"
|
||||||
)
|
)
|
||||||
, nrounds = 2
|
, nrounds = 2
|
||||||
, watchlist = watchlist
|
, evals = evals
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user