From 5273772632d2fdd644580e0737857592b7436002 Mon Sep 17 00:00:00 2001 From: Temidayo Akindahunsi <98013820+TemidayoA@users.noreply.github.com> Date: Sun, 16 Aug 2026 10:52:38 +0000 Subject: [PATCH] Fix R EBM outer bag score aggregation Signed-off-by: Temidayo Akindahunsi <98013820+TemidayoA@users.noreply.github.com> --- R/R/ebm.R | 6 +++++- R/build.R | 9 +++++++++ R/tests/outer_bag_aggregation.R | 29 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 R/tests/outer_bag_aggregation.R diff --git a/R/R/ebm.R b/R/R/ebm.R index 6090763f4..2e64d206b 100644 --- a/R/R/ebm.R +++ b/R/R/ebm.R @@ -112,7 +112,11 @@ ebm_classify <- function( rng ) for(i_feature in 1:n_features) { - term_scores[[col_names[i_feature]]] <- result_list$model_update[[i_feature]] + if(1 == i_outer_bag) { + term_scores[[col_names[i_feature]]] <- result_list$model_update[[i_feature]] + } else { + term_scores[[col_names[i_feature]]] <- term_scores[[col_names[i_feature]]] + result_list$model_update[[i_feature]] + } } } for(col_name in col_names) { diff --git a/R/build.R b/R/build.R index de805ff56..5dcb5554f 100644 --- a/R/build.R +++ b/R/build.R @@ -56,6 +56,15 @@ for (file in list.files(file.path(root_path, "R"))) { file.copy(from = file.path(root_path, "R", file), to = file.path(dest_path, "R", file)) } +# tests directory +tests_path <- file.path(root_path, "tests") +if(dir.exists(tests_path)) { + dir.create(file.path(dest_path, "tests")) + for (file in list.files(tests_path)) { + file.copy(from = file.path(tests_path, file), to = file.path(dest_path, "tests", file)) + } +} + # src directory (R C++ files) dir.create(file.path(dest_path, "src")) file.copy(from = file.path(root_path, "src", "interpret_R.cpp"), to = file.path(dest_path, "src", "interpret_R.cpp")) diff --git a/R/tests/outer_bag_aggregation.R b/R/tests/outer_bag_aggregation.R new file mode 100644 index 000000000..5d1c290eb --- /dev/null +++ b/R/tests/outer_bag_aggregation.R @@ -0,0 +1,29 @@ +# Copyright (c) 2026 The InterpretML Contributors +# +# Licensed under the MIT license. + +library(interpret) + +X <- data.frame(x = seq_len(100)) +y <- c(rep(0, 90), rep(1, 10)) + +model <- ebm_classify( + X, + y, + outer_bags = 16, + random_state = 42 +) + +probabilities <- ebm_predict_proba(model, X) +difference <- abs(mean(probabilities) - mean(y)) + +if(0.02 <= difference) { + stop( + sprintf( + "Expected mean probability near %.9f, got %.9f", + mean(y), + mean(probabilities) + ), + call. = FALSE + ) +}