From f59c78d5883f2cafc714c62efd26acebcce68935 Mon Sep 17 00:00:00 2001 From: Emil Hvitfeldt Date: Sun, 30 Nov 2025 17:04:02 -0800 Subject: [PATCH 1/3] make xgboost work for all versions --- R/discretize_xgb.R | 54 +++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/R/discretize_xgb.R b/R/discretize_xgb.R index 76eb21ff..e18f2d4a 100644 --- a/R/discretize_xgb.R +++ b/R/discretize_xgb.R @@ -206,20 +206,38 @@ run_xgboost <- function( ) } - xgboost::xgb.train( - params = .params, - nrounds = 100, - data = .train, - watchlist = list( - train = .train, - test = .test - ), - tree_method = "hist", - early_stopping_rounds = 10, - objective = .objective, - verbose = 0, - nthread = 1 - ) + if (utils::packageVersion("xgboost") >= "2.0.0.0") { + .params$tree_method = "hist" + .params$nthread = 1 + .params$objective = .objective + + xgboost::xgb.train( + params = .params, + nrounds = 100, + data = .train, + evals = list( + train = .train, + test = .test + ), + early_stopping_rounds = 10, + verbose = 0 + ) + } else { + xgboost::xgb.train( + params = .params, + nrounds = 100, + data = .train, + watchlist = list( + train = .train, + test = .test + ), + tree_method = "hist", + early_stopping_rounds = 10, + objective = .objective, + verbose = 0, + nthread = 1 + ) + } } xgb_binning <- function( @@ -373,10 +391,16 @@ xgb_binning <- function( # inform the user that the dataset is insufficient for this particular case # https://github.com/dmlc/xgboost/issues/2876 # https://stackoverflow.com/questions/42670033/r-getting-non-tree-model-detected-this-function-can-only-be-used-with-tree-mo + if (utils::packageVersion("xgboost") >= "2.0.0.0") { + best_iteration <- attr(xgb_mdl, "early_stop")$best_iteration + } else { + best_iteration <- xgb_mdl$best_iteration + } + xgb_tree <- try( xgboost::xgb.model.dt.tree( model = xgb_mdl, - trees = 1:xgb_mdl$best_iteration, + trees = seq_len(best_iteration), use_int_id = TRUE ), silent = TRUE From 953f06df3ae5f5e8f6cc1415f28d0c3cfceffd07 Mon Sep 17 00:00:00 2001 From: Emil Hvitfeldt Date: Sun, 30 Nov 2025 17:04:06 -0800 Subject: [PATCH 2/3] update tests --- .../_snaps/1.7.11.1/discretize_xgb.md | 241 ++++++++++++++++++ .../testthat/_snaps/3.1.2.1/discretize_xgb.md | 208 +++++++++++++++ tests/testthat/_snaps/discretize_xgb.md | 241 ------------------ tests/testthat/test-discretize_xgb.R | 130 +++++++--- 4 files changed, 544 insertions(+), 276 deletions(-) create mode 100644 tests/testthat/_snaps/1.7.11.1/discretize_xgb.md create mode 100644 tests/testthat/_snaps/3.1.2.1/discretize_xgb.md diff --git a/tests/testthat/_snaps/1.7.11.1/discretize_xgb.md b/tests/testthat/_snaps/1.7.11.1/discretize_xgb.md new file mode 100644 index 00000000..41c7c6e5 --- /dev/null +++ b/tests/testthat/_snaps/1.7.11.1/discretize_xgb.md @@ -0,0 +1,241 @@ +# run_xgboost for classification + + Code + xgboost + Output + ##### xgb.Booster + raw: 74.2 Kb + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + watchlist = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10, tree_method = "hist", objective = .objective, + nthread = 1) + params (as set within xgb.train): + eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", tree_method = "hist", objective = "binary:logistic", nthread = "1", validate_parameters = "TRUE" + xgb.attributes: + best_iteration, best_msg, best_ntreelimit, best_score, niter + callbacks: + cb.evaluation.log() + cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, + verbose = verbose) + # of features: 13 + niter: 96 + best_iteration : 86 + best_ntreelimit : 86 + best_score : 0.4421503 + best_msg : [86] train-logloss:0.417583 test-logloss:0.442150 + nfeatures : 13 + evaluation_log: + iter train_logloss test_logloss + + 1 0.6279229 0.6303495 + 2 0.5869984 0.5894989 + --- --- --- + 95 0.4157892 0.4425857 + 96 0.4156102 0.4432699 + +# run_xgboost for multi-classification + + Code + xgboost + Output + ##### xgb.Booster + raw: 149.7 Kb + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + watchlist = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10, tree_method = "hist", objective = .objective, + nthread = 1) + params (as set within xgb.train): + eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", num_class = "6", tree_method = "hist", objective = "multi:softprob", nthread = "1", validate_parameters = "TRUE" + xgb.attributes: + best_iteration, best_msg, best_ntreelimit, best_score, niter + callbacks: + cb.evaluation.log() + cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, + verbose = verbose) + # of features: 30 + niter: 33 + best_iteration : 23 + best_ntreelimit : 23 + best_score : 1.246428 + best_msg : [23] train-mlogloss:1.178121 test-mlogloss:1.246428 + nfeatures : 30 + evaluation_log: + iter train_mlogloss test_mlogloss + + 1 1.623174 1.631783 + 2 1.515108 1.531188 + --- --- --- + 32 1.159813 1.249701 + 33 1.158088 1.250462 + +# run_xgboost for regression + + Code + xgboost + Output + ##### xgb.Booster + raw: 40.2 Kb + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + watchlist = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10, tree_method = "hist", objective = .objective, + nthread = 1) + params (as set within xgb.train): + eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", tree_method = "hist", objective = "reg:squarederror", nthread = "1", validate_parameters = "TRUE" + xgb.attributes: + best_iteration, best_msg, best_ntreelimit, best_score, niter + callbacks: + cb.evaluation.log() + cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, + verbose = verbose) + # of features: 73 + niter: 50 + best_iteration : 40 + best_ntreelimit : 40 + best_score : 0.1165337 + best_msg : [40] train-rmse:0.064010 test-rmse:0.116534 + nfeatures : 73 + evaluation_log: + iter train_rmse test_rmse + + 1 3.31007782 3.3068878 + 2 2.31969213 2.3262197 + --- --- --- + 49 0.06207940 0.1175223 + 50 0.06191289 0.1188113 + +# xgb_binning for classification + + Code + xgb_binning + Output + [1] 1 2 3 5 6 9 12 15 20 + +# xgb_binning for multi-classification + + Code + xgb_binning + Output + [1] 26 31 35 38 + +# xgb_binning for regression + + Code + xgb_binning + Output + [1] 42.01972 42.02510 42.03122 42.03462 42.03840 42.04638 42.05236 42.05917 + +# step_discretize_xgb for classification + + Code + xgb_train_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.6808, Inf] [0.4208,0.7999) a + 2 [0.5749,0.6808) [0.4208,0.7999) b + 3 [0.3687,0.5749) [-Inf,0.3327) b + 4 [0.5749,0.6808) [0.4208,0.7999) b + 5 [0.6808, Inf] [0.4208,0.7999) a + 6 [0.5749,0.6808) [0.7999, Inf] a + 7 [0.5749,0.6808) [-Inf,0.3327) b + 8 [0.5749,0.6808) [-Inf,0.3327) a + 9 [0.2779,0.3687) [0.4208,0.7999) a + 10 [0.3687,0.5749) [0.4208,0.7999) b + +--- + + Code + xgb_test_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.5749,0.6808) [-Inf,0.3327) b + 2 [0.5749,0.6808) [0.4208,0.7999) b + 3 [0.3687,0.5749) [-Inf,0.3327) b + 4 [0.2779,0.3687) [0.4208,0.7999) b + 5 [0.6808, Inf] [0.7999, Inf] a + 6 [0.3687,0.5749) [-Inf,0.3327) b + 7 [0.2779,0.3687) [0.4208,0.7999) a + 8 [0.6808, Inf] [0.7999, Inf] a + 9 [0.3687,0.5749) [0.7999, Inf] b + 10 [0.3687,0.5749) [0.4208,0.7999) b + +--- + + Code + prep(step_discretize_xgb(recipe(class ~ ., data = sim_tr_cls[1:9, ]), + all_predictors(), outcome = "class")) + Condition + Error in `step_discretize_xgb()`: + Caused by error in `prep()`: + ! Too few observations in the early stopping validation set. + i Consider increasing the `sample_val` parameter. + +--- + + Code + set.seed(1) + prep(step_discretize_xgb(recipe(Status ~ ., data = credit_data_train), Time, + outcome = "Status"), retain = TRUE) + Condition + Warning: + More than 20 unique training set values are required. + i Predictors 'Time' were not processed; their original values will be used. + Message + + -- Recipe ---------------------------------------------------------------------- + + -- Inputs + Number of variables by role + outcome: 1 + predictor: 13 + + -- Training information + Training data contained 3340 data points and 301 incomplete rows. + + -- Operations + * Discretizing variables using xgboost: | Trained + +# step_discretize_xgb for multi-classification + + Code + xgb_train_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.6879, Inf] [0.3274, Inf] c + 2 [0.5863,0.6879) [0.3274, Inf] b + 3 [0.3821,0.5863) [-Inf,0.3274) b + 4 [0.5863,0.6879) [0.3274, Inf] b + 5 [0.6879, Inf] [0.3274, Inf] c + 6 [0.5863,0.6879) [0.3274, Inf] c + 7 [0.5863,0.6879) [-Inf,0.3274) b + 8 [0.5863,0.6879) [-Inf,0.3274) c + 9 [-Inf,0.2887) [0.3274, Inf] a + 10 [0.3821,0.5863) [0.3274, Inf] b + +--- + + Code + xgb_test_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.5863,0.6879) [-Inf,0.3274) b + 2 [0.5863,0.6879) [0.3274, Inf] b + 3 [0.3821,0.5863) [-Inf,0.3274) b + 4 [0.2887,0.3821) [0.3274, Inf] b + 5 [0.6879, Inf] [0.3274, Inf] c + 6 [0.3821,0.5863) [-Inf,0.3274) b + 7 [0.2887,0.3821) [0.3274, Inf] a + 8 [0.6879, Inf] [0.3274, Inf] c + 9 [0.3821,0.5863) [0.3274, Inf] b + 10 [0.3821,0.5863) [0.3274, Inf] b + diff --git a/tests/testthat/_snaps/3.1.2.1/discretize_xgb.md b/tests/testthat/_snaps/3.1.2.1/discretize_xgb.md new file mode 100644 index 00000000..7c587035 --- /dev/null +++ b/tests/testthat/_snaps/3.1.2.1/discretize_xgb.md @@ -0,0 +1,208 @@ +# run_xgboost for classification + + Code + xgboost + Output + ##### xgb.Booster + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + evals = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10) + # of features: 13 + # of rounds: 80 + xgb.attributes: + best_iteration, best_score + callbacks: + early_stop, evaluation_log + evaluation_log: + iter train_logloss test_logloss + + 1 0.5739956 0.5763535 + 2 0.5546428 0.5563444 + --- --- --- + 79 0.4189363 0.4445886 + 80 0.4186880 0.4440128 + +# run_xgboost for multi-classification + + Code + xgboost + Output + ##### xgb.Booster + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + evals = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10) + # of features: 30 + # of rounds: 33 + xgb.attributes: + best_iteration, best_score + callbacks: + early_stop, evaluation_log + evaluation_log: + iter train_mlogloss test_mlogloss + + 1 1.550003 1.558689 + 2 1.465324 1.481185 + --- --- --- + 32 1.159343 1.250772 + 33 1.157686 1.250718 + +# run_xgboost for regression + + Code + xgboost + Output + ##### xgb.Booster + call: + xgboost::xgb.train(params = .params, data = .train, nrounds = 100, + evals = list(train = .train, test = .test), verbose = 0, + early_stopping_rounds = 10) + # of features: 73 + # of rounds: 25 + xgb.attributes: + best_iteration, best_score + callbacks: + early_stop, evaluation_log + evaluation_log: + iter train_rmse test_rmse + + 1 0.15708398 0.1633305 + 2 0.14190657 0.1588983 + --- --- --- + 24 0.07039493 0.1211529 + 25 0.06975907 0.1206107 + +# xgb_binning for classification + + Code + xgb_binning + Output + [1] 1 2 3 5 6 9 12 15 20 + +# xgb_binning for multi-classification + + Code + xgb_binning + Output + [1] 26 + +# xgb_binning for regression + + Code + xgb_binning + Output + [1] 42.01972 42.02510 42.03122 42.03462 42.03840 42.04638 42.05236 42.05917 + +# step_discretize_xgb for classification + + Code + xgb_train_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.6808, Inf] [0.3327, Inf] a + 2 [0.5749,0.6808) [0.3327, Inf] b + 3 [0.3687,0.5749) [-Inf,0.3327) b + 4 [0.5749,0.6808) [0.3327, Inf] b + 5 [0.6808, Inf] [0.3327, Inf] a + 6 [0.5749,0.6808) [0.3327, Inf] a + 7 [0.5749,0.6808) [-Inf,0.3327) b + 8 [0.5749,0.6808) [-Inf,0.3327) a + 9 [0.2779,0.3687) [0.3327, Inf] a + 10 [0.3687,0.5749) [0.3327, Inf] b + +--- + + Code + xgb_test_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.5749,0.6808) [-Inf,0.3327) b + 2 [0.5749,0.6808) [0.3327, Inf] b + 3 [0.3687,0.5749) [-Inf,0.3327) b + 4 [0.2779,0.3687) [0.3327, Inf] b + 5 [0.6808, Inf] [0.3327, Inf] a + 6 [0.3687,0.5749) [-Inf,0.3327) b + 7 [0.2779,0.3687) [0.3327, Inf] a + 8 [0.6808, Inf] [0.3327, Inf] a + 9 [0.3687,0.5749) [0.3327, Inf] b + 10 [0.3687,0.5749) [0.3327, Inf] b + +--- + + Code + prep(step_discretize_xgb(recipe(class ~ ., data = sim_tr_cls[1:9, ]), + all_predictors(), outcome = "class")) + Condition + Error in `step_discretize_xgb()`: + Caused by error in `prep()`: + ! Too few observations in the early stopping validation set. + i Consider increasing the `sample_val` parameter. + +--- + + Code + set.seed(1) + prep(step_discretize_xgb(recipe(Status ~ ., data = credit_data_train), Time, + outcome = "Status"), retain = TRUE) + Condition + Warning: + More than 20 unique training set values are required. + i Predictors 'Time' were not processed; their original values will be used. + Message + + -- Recipe ---------------------------------------------------------------------- + + -- Inputs + Number of variables by role + outcome: 1 + predictor: 13 + + -- Training information + Training data contained 3340 data points and 301 incomplete rows. + + -- Operations + * Discretizing variables using xgboost: | Trained + +# step_discretize_xgb for multi-classification + + Code + xgb_train_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.6879, Inf] [0.09924, Inf] c + 2 [0.5863,0.6879) [0.09924, Inf] b + 3 [0.3821,0.5863) [-Inf,0.09924) b + 4 [0.5863,0.6879) [0.09924, Inf] b + 5 [0.6879, Inf] [0.09924, Inf] c + 6 [0.5863,0.6879) [0.09924, Inf] c + 7 [0.5863,0.6879) [-Inf,0.09924) b + 8 [0.5863,0.6879) [0.09924, Inf] c + 9 [-Inf,0.2887) [0.09924, Inf] a + 10 [0.3821,0.5863) [0.09924, Inf] b + +--- + + Code + xgb_test_bins[1:10, ] + Output + # A tibble: 10 x 3 + x z class + + 1 [0.5863,0.6879) [0.09924, Inf] b + 2 [0.5863,0.6879) [0.09924, Inf] b + 3 [0.3821,0.5863) [0.09924, Inf] b + 4 [0.2887,0.3821) [0.09924, Inf] b + 5 [0.6879, Inf] [0.09924, Inf] c + 6 [0.3821,0.5863) [-Inf,0.09924) b + 7 [0.2887,0.3821) [0.09924, Inf] a + 8 [0.6879, Inf] [0.09924, Inf] c + 9 [0.3821,0.5863) [0.09924, Inf] b + 10 [0.3821,0.5863) [0.09924, Inf] b + diff --git a/tests/testthat/_snaps/discretize_xgb.md b/tests/testthat/_snaps/discretize_xgb.md index 43eb7821..0f837961 100644 --- a/tests/testthat/_snaps/discretize_xgb.md +++ b/tests/testthat/_snaps/discretize_xgb.md @@ -1,127 +1,5 @@ -# run_xgboost for classification - - Code - xgboost - Output - ##### xgb.Booster - raw: 74.2 Kb - call: - xgboost::xgb.train(params = .params, data = .train, nrounds = 100, - watchlist = list(train = .train, test = .test), verbose = 0, - early_stopping_rounds = 10, tree_method = "hist", objective = .objective, - nthread = 1) - params (as set within xgb.train): - eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", tree_method = "hist", objective = "binary:logistic", nthread = "1", validate_parameters = "TRUE" - xgb.attributes: - best_iteration, best_msg, best_ntreelimit, best_score, niter - callbacks: - cb.evaluation.log() - cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, - verbose = verbose) - # of features: 13 - niter: 96 - best_iteration : 86 - best_ntreelimit : 86 - best_score : 0.4421503 - best_msg : [86] train-logloss:0.417583 test-logloss:0.442150 - nfeatures : 13 - evaluation_log: - iter train_logloss test_logloss - - 1 0.6279229 0.6303495 - 2 0.5869984 0.5894989 - --- --- --- - 95 0.4157892 0.4425857 - 96 0.4156102 0.4432699 - -# run_xgboost for multi-classification - - Code - xgboost - Output - ##### xgb.Booster - raw: 149.7 Kb - call: - xgboost::xgb.train(params = .params, data = .train, nrounds = 100, - watchlist = list(train = .train, test = .test), verbose = 0, - early_stopping_rounds = 10, tree_method = "hist", objective = .objective, - nthread = 1) - params (as set within xgb.train): - eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", num_class = "6", tree_method = "hist", objective = "multi:softprob", nthread = "1", validate_parameters = "TRUE" - xgb.attributes: - best_iteration, best_msg, best_ntreelimit, best_score, niter - callbacks: - cb.evaluation.log() - cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, - verbose = verbose) - # of features: 30 - niter: 33 - best_iteration : 23 - best_ntreelimit : 23 - best_score : 1.246428 - best_msg : [23] train-mlogloss:1.178121 test-mlogloss:1.246428 - nfeatures : 30 - evaluation_log: - iter train_mlogloss test_mlogloss - - 1 1.623174 1.631783 - 2 1.515108 1.531188 - --- --- --- - 32 1.159813 1.249701 - 33 1.158088 1.250462 - -# run_xgboost for regression - - Code - xgboost - Output - ##### xgb.Booster - raw: 40.2 Kb - call: - xgboost::xgb.train(params = .params, data = .train, nrounds = 100, - watchlist = list(train = .train, test = .test), verbose = 0, - early_stopping_rounds = 10, tree_method = "hist", objective = .objective, - nthread = 1) - params (as set within xgb.train): - eta = "0.3", max_bin = "10", max_depth = "1", min_child_weight = "5", tree_method = "hist", objective = "reg:squarederror", nthread = "1", validate_parameters = "TRUE" - xgb.attributes: - best_iteration, best_msg, best_ntreelimit, best_score, niter - callbacks: - cb.evaluation.log() - cb.early.stop(stopping_rounds = early_stopping_rounds, maximize = maximize, - verbose = verbose) - # of features: 73 - niter: 50 - best_iteration : 40 - best_ntreelimit : 40 - best_score : 0.1165337 - best_msg : [40] train-rmse:0.064010 test-rmse:0.116534 - nfeatures : 73 - evaluation_log: - iter train_rmse test_rmse - - 1 3.31007782 3.3068878 - 2 2.31969213 2.3262197 - --- --- --- - 49 0.06207940 0.1175223 - 50 0.06191289 0.1188113 - -# xgb_binning for classification - - Code - xgb_binning - Output - [1] 1 2 3 5 6 9 12 15 20 - # xgb_binning for multi-classification - Code - xgb_binning - Output - [1] 26 31 35 38 - ---- - Code embed:::xgb_binning(attrition_data_small, "EducationField", "Age", sample_val = 0.3, learn_rate = 0.3, num_breaks = 10, tree_depth = 1, min_n = 5) @@ -130,133 +8,14 @@ # xgb_binning for regression - Code - xgb_binning - Output - [1] 42.01972 42.02510 42.03122 42.03462 42.03840 42.04638 42.05236 42.05917 - ---- - Code embed:::xgb_binning(ames_data_small, "Sale_Price", "Latitude", sample_val = 0.3, learn_rate = 0.3, num_breaks = 10, tree_depth = 1, min_n = 5) Output numeric(0) -# step_discretize_xgb for classification - - Code - xgb_train_bins[1:10, ] - Output - # A tibble: 10 x 3 - x z class - - 1 [0.6808, Inf] [0.4208,0.7999) a - 2 [0.5749,0.6808) [0.4208,0.7999) b - 3 [0.3687,0.5749) [-Inf,0.3327) b - 4 [0.5749,0.6808) [0.4208,0.7999) b - 5 [0.6808, Inf] [0.4208,0.7999) a - 6 [0.5749,0.6808) [0.7999, Inf] a - 7 [0.5749,0.6808) [-Inf,0.3327) b - 8 [0.5749,0.6808) [-Inf,0.3327) a - 9 [0.2779,0.3687) [0.4208,0.7999) a - 10 [0.3687,0.5749) [0.4208,0.7999) b - ---- - - Code - xgb_test_bins[1:10, ] - Output - # A tibble: 10 x 3 - x z class - - 1 [0.5749,0.6808) [-Inf,0.3327) b - 2 [0.5749,0.6808) [0.4208,0.7999) b - 3 [0.3687,0.5749) [-Inf,0.3327) b - 4 [0.2779,0.3687) [0.4208,0.7999) b - 5 [0.6808, Inf] [0.7999, Inf] a - 6 [0.3687,0.5749) [-Inf,0.3327) b - 7 [0.2779,0.3687) [0.4208,0.7999) a - 8 [0.6808, Inf] [0.7999, Inf] a - 9 [0.3687,0.5749) [0.7999, Inf] b - 10 [0.3687,0.5749) [0.4208,0.7999) b - ---- - - Code - prep(step_discretize_xgb(recipe(class ~ ., data = sim_tr_cls[1:9, ]), - all_predictors(), outcome = "class")) - Condition - Error in `step_discretize_xgb()`: - Caused by error in `prep()`: - ! Too few observations in the early stopping validation set. - i Consider increasing the `sample_val` parameter. - ---- - - Code - set.seed(1) - prep(step_discretize_xgb(recipe(Status ~ ., data = credit_data_train), Time, - outcome = "Status"), retain = TRUE) - Condition - Warning: - More than 20 unique training set values are required. - i Predictors 'Time' were not processed; their original values will be used. - Message - - -- Recipe ---------------------------------------------------------------------- - - -- Inputs - Number of variables by role - outcome: 1 - predictor: 13 - - -- Training information - Training data contained 3340 data points and 301 incomplete rows. - - -- Operations - * Discretizing variables using xgboost: | Trained - # step_discretize_xgb for multi-classification - Code - xgb_train_bins[1:10, ] - Output - # A tibble: 10 x 3 - x z class - - 1 [0.6879, Inf] [0.3274, Inf] c - 2 [0.5863,0.6879) [0.3274, Inf] b - 3 [0.3821,0.5863) [-Inf,0.3274) b - 4 [0.5863,0.6879) [0.3274, Inf] b - 5 [0.6879, Inf] [0.3274, Inf] c - 6 [0.5863,0.6879) [0.3274, Inf] c - 7 [0.5863,0.6879) [-Inf,0.3274) b - 8 [0.5863,0.6879) [-Inf,0.3274) c - 9 [-Inf,0.2887) [0.3274, Inf] a - 10 [0.3821,0.5863) [0.3274, Inf] b - ---- - - Code - xgb_test_bins[1:10, ] - Output - # A tibble: 10 x 3 - x z class - - 1 [0.5863,0.6879) [-Inf,0.3274) b - 2 [0.5863,0.6879) [0.3274, Inf] b - 3 [0.3821,0.5863) [-Inf,0.3274) b - 4 [0.2887,0.3821) [0.3274, Inf] b - 5 [0.6879, Inf] [0.3274, Inf] c - 6 [0.3821,0.5863) [-Inf,0.3274) b - 7 [0.2887,0.3821) [0.3274, Inf] a - 8 [0.6879, Inf] [0.3274, Inf] c - 9 [0.3821,0.5863) [0.3274, Inf] b - 10 [0.3821,0.5863) [0.3274, Inf] b - ---- - Code prep(step_discretize_xgb(recipe(class ~ ., data = sim_tr_mcls[1:9, ]), all_predictors(), outcome = "class")) diff --git a/tests/testthat/test-discretize_xgb.R b/tests/testthat/test-discretize_xgb.R index a2c9c053..a7bba67a 100644 --- a/tests/testthat/test-discretize_xgb.R +++ b/tests/testthat/test-discretize_xgb.R @@ -121,12 +121,22 @@ test_that("run_xgboost for classification", { .objective = "binary:logistic", .num_class = NA ) - - expect_snapshot(xgboost, transform = trimws) - expect_equal(length(xgboost$params), 8) - expect_equal(xgboost$nfeatures, 13) - expect_equal(xgboost$params$tree_method, "hist") - expect_equal(xgboost$params$objective, "binary:logistic") + expect_snapshot( + xgboost, + transform = trimws, + variant = as.character(packageVersion("xgboost")) + ) + if (utils::packageVersion("xgboost") >= "2.0.0.0") { + expect_equal(length(attr(xgboost, "params")), 9) + expect_equal(length(xgboost::getinfo(xgboost, "feature_name")), 13) + expect_equal(attr(xgboost, "params")$tree_method, "hist") + expect_equal(attr(xgboost, "params")$objective, "binary:logistic") + } else { + expect_equal(length(xgboost$params), 8) + expect_equal(xgboost$nfeatures, 13) + expect_equal(xgboost$params$tree_method, "hist") + expect_equal(xgboost$params$objective, "binary:logistic") + } }) test_that("run_xgboost for multi-classification", { @@ -143,11 +153,22 @@ test_that("run_xgboost for multi-classification", { .objective = "multi:softprob" ) - expect_snapshot(xgboost, transform = trimws) - expect_equal(length(xgboost$params), 9) - expect_equal(xgboost$nfeatures, 30) - expect_equal(xgboost$params$tree_method, "hist") - expect_equal(xgboost$params$objective, "multi:softprob") + expect_snapshot( + xgboost, + transform = trimws, + variant = as.character(packageVersion("xgboost")) + ) + if (utils::packageVersion("xgboost") >= "2.0.0.0") { + expect_equal(length(attr(xgboost, "params")), 10) + expect_equal(length(xgboost::getinfo(xgboost, "feature_name")), 30) + expect_equal(attr(xgboost, "params")$tree_method, "hist") + expect_equal(attr(xgboost, "params")$objective, "multi:softprob") + } else { + expect_equal(length(xgboost$params), 9) + expect_equal(xgboost$nfeatures, 30) + expect_equal(xgboost$params$tree_method, "hist") + expect_equal(xgboost$params$objective, "multi:softprob") + } }) test_that("run_xgboost for regression", { @@ -164,11 +185,22 @@ test_that("run_xgboost for regression", { .num_class = NA ) - expect_snapshot(xgboost, transform = trimws) - expect_true(length(xgboost$params) > 1) - expect_true(xgboost$nfeatures > 1) - expect_equal(xgboost$params$tree_method, "hist") - expect_equal(xgboost$params$objective, "reg:squarederror") + expect_snapshot( + xgboost, + transform = trimws, + variant = as.character(packageVersion("xgboost")) + ) + if (utils::packageVersion("xgboost") >= "2.0.0.0") { + expect_equal(length(attr(xgboost, "params")), 9) + expect_true(length(xgboost::getinfo(xgboost, "feature_name")) > 1) + expect_equal(attr(xgboost, "params")$tree_method, "hist") + expect_equal(attr(xgboost, "params")$objective, "reg:squarederror") + } else { + expect_true(length(xgboost$params) > 1) + expect_true(xgboost$nfeatures > 1) + expect_equal(xgboost$params$tree_method, "hist") + expect_equal(xgboost$params$objective, "reg:squarederror") + } }) test_that("xgb_binning for classification", { @@ -187,7 +219,10 @@ test_that("xgb_binning for classification", { min_n = 5 ) - expect_snapshot(xgb_binning) + expect_snapshot( + xgb_binning, + variant = as.character(packageVersion("xgboost")) + ) expect_true(length(xgb_binning) > 1) expect_type(xgb_binning, "double") @@ -223,8 +258,11 @@ test_that("xgb_binning for multi-classification", { min_n = 5 ) - expect_snapshot(xgb_binning) - expect_true(length(xgb_binning) > 1) + expect_snapshot( + xgb_binning, + variant = as.character(packageVersion("xgboost")) + ) + expect_true(length(xgb_binning) >= 1) expect_type(xgb_binning, "double") # Algorithm runs on a too small training set/ insufficient variation in data @@ -258,7 +296,10 @@ test_that("xgb_binning for regression", { min_n = 5 ) - expect_snapshot(xgb_binning) + expect_snapshot( + xgb_binning, + variant = as.character(packageVersion("xgboost")) + ) expect_true(length(xgb_binning) > 1) expect_type(xgb_binning, "double") @@ -293,8 +334,14 @@ test_that("step_discretize_xgb for classification", { xgb_train_bins <- bake(xgb_rec, sim_tr_cls) xgb_test_bins <- bake(xgb_rec, sim_te_cls) - expect_snapshot(xgb_train_bins[1:10, ]) - expect_snapshot(xgb_test_bins[1:10, ]) + expect_snapshot( + xgb_train_bins[1:10, ], + variant = as.character(packageVersion("xgboost")) + ) + expect_snapshot( + xgb_test_bins[1:10, ], + variant = as.character(packageVersion("xgboost")) + ) expect_true(length(levels(xgb_train_bins$x)) > 1) expect_true(length(levels(xgb_train_bins$z)) > 1) @@ -308,11 +355,15 @@ test_that("step_discretize_xgb for classification", { ) # Too few data - expect_snapshot(error = TRUE, { - recipe(class ~ ., data = sim_tr_cls[1:9, ]) |> - step_discretize_xgb(all_predictors(), outcome = "class") |> - prep() - }) + expect_snapshot( + error = TRUE, + { + recipe(class ~ ., data = sim_tr_cls[1:9, ]) |> + step_discretize_xgb(all_predictors(), outcome = "class") |> + prep() + }, + variant = as.character(packageVersion("xgboost")) + ) # No numeric variables present predictors_non_numeric <- c( @@ -328,12 +379,15 @@ test_that("step_discretize_xgb for classification", { step_discretize_xgb(all_numeric(), outcome = "Status") # Information about insufficient datapoints for Time predictor - expect_snapshot({ - set.seed(1) - recipe(Status ~ ., data = credit_data_train) |> - step_discretize_xgb(Time, outcome = "Status") |> - prep(retain = TRUE) - }) + expect_snapshot( + { + set.seed(1) + recipe(Status ~ ., data = credit_data_train) |> + step_discretize_xgb(Time, outcome = "Status") |> + prep(retain = TRUE) + }, + variant = as.character(packageVersion("xgboost")) + ) }) test_that("step_discretize_xgb for multi-classification", { @@ -351,8 +405,14 @@ test_that("step_discretize_xgb for multi-classification", { xgb_train_bins <- bake(xgb_rec, sim_tr_mcls) xgb_test_bins <- bake(xgb_rec, sim_te_mcls) - expect_snapshot(xgb_train_bins[1:10, ]) - expect_snapshot(xgb_test_bins[1:10, ]) + expect_snapshot( + xgb_train_bins[1:10, ], + variant = as.character(packageVersion("xgboost")) + ) + expect_snapshot( + xgb_test_bins[1:10, ], + variant = as.character(packageVersion("xgboost")) + ) expect_true(length(levels(xgb_train_bins$x)) > 0) expect_true(length(levels(xgb_train_bins$z)) > 0) From 1452c4efb7ca5746681c061310d8a2276b69acd7 Mon Sep 17 00:00:00 2001 From: Emil Hvitfeldt Date: Sun, 30 Nov 2025 17:04:54 -0800 Subject: [PATCH 3/3] add news --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 68e7a672..d0012ea4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ # embed (development version) +* Make work with all versions of xgboost. (#267) + # embed 1.2.0 + ## Improvements * Adds `step_lencode()` to perform analytical likelihood encoding. (#258)