diff --git a/R-package/R/lgb.cv.R b/R-package/R/lgb.cv.R index f81026fe673f..96c55573e205 100644 --- a/R-package/R/lgb.cv.R +++ b/R-package/R/lgb.cv.R @@ -46,6 +46,9 @@ CVBooster <- R6::R6Class( #' @param eval_train_metric \code{boolean}, whether to add the cross validation results on the #' training data. This parameter defaults to \code{FALSE}. Setting it to \code{TRUE} #' will increase run time. +#' @param print_metrics \code{boolean} when calculating evaluation metrics after boosting rounds, whether +#' to print informational messages with these metrics (see parameters \code{eval_freq}, +#' \code{eval_train_metric}, and \code{eval}). #' @inheritSection lgb_shared_params Early Stopping #' @return a trained model \code{lgb.CVBooster}. #' @@ -92,6 +95,7 @@ lgb.cv <- function(params = list() , reset_data = FALSE , serializable = TRUE , eval_train_metric = FALSE + , print_metrics = TRUE ) { if (nrounds <= 0L) { @@ -244,7 +248,8 @@ lgb.cv <- function(params = list() } # Add printing log callback - if (params[["verbosity"]] > 0L && eval_freq > 0L) { + print_metrics <- as.logical(print_metrics) + if (print_metrics && eval_freq > 0L) { callbacks <- add.cb(cb_list = callbacks, cb = cb_print_evaluation(period = eval_freq)) } @@ -287,7 +292,7 @@ lgb.cv <- function(params = list() , cb = cb_early_stop( stopping_rounds = early_stopping_rounds , first_metric_only = isTRUE(params[["first_metric_only"]]) - , verbose = params[["verbosity"]] > 0L + , verbose = print_metrics ) ) } diff --git a/R-package/man/lgb.cv.Rd b/R-package/man/lgb.cv.Rd index 555cb11c7bb3..01647394cd28 100644 --- a/R-package/man/lgb.cv.Rd +++ b/R-package/man/lgb.cv.Rd @@ -26,7 +26,8 @@ lgb.cv( callbacks = list(), reset_data = FALSE, serializable = TRUE, - eval_train_metric = FALSE + eval_train_metric = FALSE, + print_metrics = TRUE ) } \arguments{ @@ -126,6 +127,10 @@ into a predictor model which frees up memory and the original datasets} \item{eval_train_metric}{\code{boolean}, whether to add the cross validation results on the training data. This parameter defaults to \code{FALSE}. Setting it to \code{TRUE} will increase run time.} + +\item{print_metrics}{\code{boolean} when calculating evaluation metrics after boosting rounds, whether +to print informational messages with these metrics (see parameters \code{eval_freq}, +\code{eval_train_metric}, and \code{eval}).} } \value{ a trained model \code{lgb.CVBooster}. diff --git a/R-package/tests/testthat/test_basic.R b/R-package/tests/testthat/test_basic.R index 9b84017476a7..c58ea9b53e51 100644 --- a/R-package/tests/testthat/test_basic.R +++ b/R-package/tests/testthat/test_basic.R @@ -3256,7 +3256,7 @@ test_that("lightgbm() accepts 'weight' and 'weights'", { expect_equal(record_evals[["valid"]][["auc"]][["eval_err"]], list()) } -.train_for_verbosity_test <- function(train_function, verbose_kwarg, verbose_param) { +.train_for_verbosity_test <- function(train_function, verbose_kwarg, verbose_param, print_metrics = FALSE) { set.seed(708L) nrounds <- 5L params <- list( @@ -3301,6 +3301,7 @@ test_that("lightgbm() accepts 'weight' and 'weights'", { ) train_kwargs[["nfold"]] <- 3L train_kwargs[["showsd"]] <- FALSE + train_kwargs[["print_metrics"]] <- print_metrics } log_txt <- capture.output({ bst <- do.call( @@ -3549,6 +3550,7 @@ test_that("lgb.cv() only prints eval metrics when expected to", { out <- .train_for_verbosity_test( verbose_kwarg = verbose_keyword_arg , verbose_param = -1L + , print_metrics = FALSE , train_function = lgb.cv ) .assert_has_expected_logs( @@ -3583,6 +3585,7 @@ test_that("lgb.cv() only prints eval metrics when expected to", { out <- .train_for_verbosity_test( verbose_kwarg = verbose_keyword_arg , verbose_param = 1L + , print_metrics = TRUE , train_function = lgb.cv ) .assert_has_expected_logs( @@ -3638,6 +3641,7 @@ test_that("lgb.cv() only prints eval metrics when expected to", { out <- .train_for_verbosity_test( verbose_kwarg = verbose_keyword_arg , verbose_param = 1L + , print_metrics = TRUE , train_function = lgb.cv ) .assert_has_expected_logs( @@ -3828,3 +3832,29 @@ test_that("Evaluation metrics aren't printed as a single-element vector", { }) expect_false(grepl("[1] \"[1]", log_txt, fixed = TRUE)) }) + +test_that("lgb.cv() doesn't mix booster messages with evaluation metrics messages", { + log_txt <- capture_output({ + data(mtcars) + y <- mtcars$mpg + x <- as.matrix(mtcars[, -1L]) + cv_result <- lgb.cv( + data = lgb.Dataset(x, label = y) + , params = list( + objective = "regression" + , metric = "l2" + , min_data_in_leaf = 5L + , max_depth = 3L + , num_threads = .LGB_MAX_THREADS + ) + , nrounds = 2L + , nfold = 3L + , verbose = -1L + , eval_train_metric = TRUE + , print_metrics = TRUE + ) + }) + expect_false(grepl("Warning", log_txt, fixed = TRUE)) + expect_false(grepl("gain", log_txt, fixed = TRUE)) + expect_false(grepl("inf", log_txt, fixed = TRUE)) +})