| Title: | Decomposing Global Feature Effects Based on Feature Interactions |
|---|---|
| Description: | Implements the GADGET (Generalized Additive Decomposition of Global EffecTs) algorithm for interpretable machine learning. The package recursively partitions the feature space to minimize heterogeneity of feature effects (e.g., Accumulated Local Effects or Partial Dependence), producing a tree of regions where effects are more stable. It supports both ALE and PD strategies, works with 'mlr3' learners and provides visualization of the interaction tree and regional effect plots. The method is described in Herbinger, J., Wright, M. N., Nagler, T., Bischl, B., and Casalicchio, G. (2024), "Decomposing Global Feature Effects Based on Feature Interactions" <https://jmlr.org/papers/volume25/23-0699/23-0699.pdf>. |
| Authors: | Zizheng Zhang [aut, cre] (ORCID: <https://orcid.org/0009-0009-4252-8018>), Coco Bögel [aut] (ORCID: <https://orcid.org/0009-0002-0683-4957>), Giuseppe Casalicchio [aut] (ORCID: <https://orcid.org/0000-0001-5324-5966>), Bernd Bischl [aut] (ORCID: <https://orcid.org/0000-0001-6002-6980>) |
| Maintainer: | Zizheng Zhang <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1 |
| Built: | 2026-10-29 12:40:34 UTC |
| Source: | https://github.com/cran/xplaineff |
The xplaineff package implements the GADGET algorithm for interpretable machine learning. It builds a tree by recursively partitioning the feature space to minimize the heterogeneity of feature effects (e.g., Accumulated Local Effects or Partial Dependence), so that within each region the effects are more stable and easier to interpret.
Main components (user-facing):
GadgetTree: R6 class to grow and visualize effect-based trees.
AleStrategy: Strategy for ALE-based trees (ALE computed internally from a fitted model).
PdStrategy: Strategy for PD-based trees (uses
precomputed ICE/PD from iml or similar tools).
Typical workflow:
Train a model (e.g., with mlr3).
Create a tree: tree = GadgetTree$new(strategy = AleStrategy$new(), n_split = 3, min_node_size = 50).
Fit: tree$fit(data, target_feature_name, ...).
Strategy-specific ... arguments include:
AleStrategy: model (required), n_intervals = 10,
predict_fun = NULL, order_method = "raw", ale_engine (default "auto"),
categorical_split, and max_exhaustive_levels.
PdStrategy: either effect, or model with optional predict_fun,
n_grid, pd_engine (default "auto"), categorical_split, and
max_exhaustive_levels.
Both strategies accept feature_set and split_feature.
Tree parameters include impr_par, min_node_size, and n_quantiles.
Visualize: tree$plot_tree_structure(), tree$plot(...), tree$extract_split_info().
For PD-based trees, either pass an effect object from
iml::FeatureEffects(..., method = "ice") to
tree$fit(effect = ..., data = ..., target_feature_name = ...),
or pass a fitted model and let xplaineff compute PD/ICE internally.
Maintainer: Zizheng Zhang [email protected]
Herbinger, J., Wright, M. N., Nagler, T., Bischl, B., and Casalicchio, G. (2024). Decomposing Global Feature Effects Based on Feature Interactions. Journal of Machine Learning Research, 25(23-0699), 1–65. URL: https://jmlr.org/papers/volume25/23-0699/23-0699.pdf.
Apley, D.W. and Zhu, J. (2016). Visualizing the Effects of Predictors on the Response in Nonlinear and Generalized Linear Models. Journal of Computational and Graphical Statistics, 25(2), 590–600.
GadgetTree, AleStrategy, PdStrategy
ALE-based effect strategy (inherits from EffectStrategy). Given model and data,
preprocesses to Z/Y via prepare_split_data_ale;
transforms ALE effects per node; computes ALE-derivative heterogeneity;
finds best split via search_best_split_ale; fits tree and plots ALE curves.
R6::R6Class object inheriting from EffectStrategy.
Intended for use through GadgetTree$new(strategy = AleStrategy$new()) and
tree$fit(...). Can be instantiated directly for custom pipelines.
s = AleStrategy$new(categorical_split = "ordered_prefix")
::EffectStrategy -> AleStrategy
model(any)
Fitted model (persistent after $fit()).
data(data.frame() or data.table())
Data (persistent after $fit()).
target_feature_name(character(1))
Target variable name.
n_intervals(integer(1))
Intervals for numeric ALE.
predict_fun(function()) function(model, data) returning predictions.
order_method(character(1))
Categorical order: "mds", "pca", "random", "raw".
ale_engine(character(1))
ALE backend selected after $fit(): "cpp" or "r".
categorical_split(character(1))
Categorical split mode for ALE trees: "ordered_prefix" or "exhaustive".
max_exhaustive_levels(integer(1))
Maximum observed levels allowed for exhaustive categorical split search.
effect(list() or NULL)
Cached ALE effect used when $plot() omits effect.
new()
AleStrategy$new( categorical_split = "ordered_prefix", max_exhaustive_levels = 12L )
preprocess()
AleStrategy$preprocess(
model,
effect = NULL,
data,
target_feature_name,
n_intervals,
feature_set = NULL,
split_feature = NULL,
predict_fun = NULL,
order_method = "raw",
ale_engine = c("auto", "cpp", "r")
)node_transform()
AleStrategy$node_transform(Y, idx, grid = NULL, is_child = FALSE)
heterogeneity()
AleStrategy$heterogeneity(Y)
get_child_objectives()
AleStrategy$get_child_objectives( Y, split_info, idx_left, idx_right, grid_left, grid_right )
find_best_split()
AleStrategy$find_best_split(Z, Y, min_node_size, n_quantiles)
plot()
AleStrategy$plot( tree, effect = NULL, data, target_feature_name, depth = NULL, node_id = NULL, features = NULL, show_plot = TRUE, show_point = TRUE, mean_center = TRUE, ... )
fit()
AleStrategy$fit(
tree,
model = NULL,
effect = NULL,
data,
target_feature_name,
n_intervals = 10,
feature_set = NULL,
split_feature = NULL,
predict_fun = NULL,
order_method = "raw",
ale_engine = c("auto", "cpp", "r"),
categorical_split = NULL,
max_exhaustive_levels = NULL,
...
)clean()
AleStrategy$clean()
clone()
The objects of this class are cloneable with this method.
AleStrategy$clone(deep = FALSE)
deepWhether to make a deep clone.
calculate_ale_heterogeneity_cpp
ale_strat = AleStrategy$new() ale_strat$categorical_splitale_strat = AleStrategy$new() ale_strat$categorical_split
Wrapper for effect-based trees: given a strategy (pd/ale), fits tree via
$fit(), plots effects via $plot(), extracts splits via
$extract_split_info().
Delegates all effect logic to the strategy.
R6::R6Class object.
This class manages the overall tree structure and delegates effect-specific operations (such as splitting and plotting) to the provided strategy object. It is the main entry point for fitting and visualizing effect-based decision trees in the xplaineff package.
t = GadgetTree$new(strategy, n_split = 2, impr_par = 0.1, min_node_size = 10, n_quantiles = NULL)
strategy :: (AleStrategy | PdStrategy)
Effect strategy object.
n_split :: integer(1)
Maximum split depth, counted as splits along any root-to-leaf path.
impr_par :: numeric(1)
Improvement threshold.
min_node_size :: integer(1)
Minimum samples per node.
n_quantiles :: integer(1) or NULL
Number of quantile cut points for numeric split candidates; NULL = use all unique values.
strategy(PdStrategy | AleStrategy)
Effect-specific logic.
root(Node)
Root node.
n_split(integer(1))
Maximum split depth, counted as splits along any root-to-leaf path.
impr_par(numeric(1))
Improvement threshold.
min_node_size(integer(1))
Minimum samples per node.
n_quantiles(integer(1) or NULL)
Number of quantile cut points for numeric split candidates.
split_benchmark(list())
Internal split timing records.
tree_list_cache(list() or NULL)
Cached depth-based tree list; invalidated on $fit().
new()
GadgetTree$new( strategy, n_split = 2, impr_par = 0.1, min_node_size = 10, n_quantiles = NULL )
fit()
GadgetTree$fit( data, target_feature_name, feature_set = NULL, split_feature = NULL, ... )
plot()
GadgetTree$plot( data, target_feature_name, effect = NULL, depth = NULL, node_id = NULL, features = NULL, ... )
plot_tree_structure()
GadgetTree$plot_tree_structure( label_wrap_width = 34L, node_spread_x = 1.55, node_spread_y = 1.12 )
extract_split_info()
GadgetTree$extract_split_info(include_timing = FALSE)
get_tree_list()
GadgetTree$get_tree_list()
clone()
The objects of this class are cloneable with this method.
GadgetTree$clone(deep = FALSE)
deepWhether to make a deep clone.
tree = GadgetTree$new(strategy = PdStrategy$new(), n_split = 2L) tree$n_splittree = GadgetTree$new(strategy = PdStrategy$new(), n_split = 2L) tree$n_split
PD-based effect strategy (inherits from EffectStrategy). Given effect or model and data,
preprocesses to Z/Y/grid;
mean-centers effects per node; computes sum-of-variances heterogeneity;
finds best split via C++; fits tree and plots PD/ICE.
Character feature columns are coerced to factor before ICE/PD computation so they match
split-matrix treatment and learner conventions (same as prepare_split_data_common).
R6::R6Class object inheriting from EffectStrategy.
This class is used internally by the GadgetTree framework to implement partial dependence tree growing, splitting, and visualization. It is not intended to be used directly by end users, but can be instantiated for advanced customization.
s = PdStrategy$new(categorical_split = "one_vs_rest")
::EffectStrategy -> PdStrategy
effect(list() or R6 or NULL)
Cached PD/ICE effect used when $plot() omits effect.
categorical_split(character(1))
Categorical split mode for PD trees: "one_vs_rest" or "exhaustive".
max_exhaustive_levels(integer(1))
Maximum observed levels allowed for exhaustive categorical split search.
new()
PdStrategy$new(categorical_split = "one_vs_rest", max_exhaustive_levels = 12L)
preprocess()
PdStrategy$preprocess( effect, data, target_feature_name = NULL, feature_set = NULL, split_feature = NULL )
node_transform()
PdStrategy$node_transform(Y, idx, grid, is_child = FALSE)
heterogeneity()
PdStrategy$heterogeneity(Y)
get_child_objectives()
PdStrategy$get_child_objectives( Y, split_info, idx_left, idx_right, grid_left, grid_right )
find_best_split()
PdStrategy$find_best_split(Z, Y, min_node_size, n_quantiles)
plot()
PdStrategy$plot( tree, effect = NULL, data, target_feature_name, depth = NULL, node_id = NULL, features = NULL, ... )
fit()
PdStrategy$fit(
tree,
effect = NULL,
model = NULL,
data,
target_feature_name,
feature_set = NULL,
split_feature = NULL,
predict_fun = NULL,
n_grid = 20L,
pd_engine = c("auto", "cpp", "r"),
categorical_split = NULL,
max_exhaustive_levels = NULL,
...
)clean()
PdStrategy$clean()
clone()
The objects of this class are cloneable with this method.
PdStrategy$clone(deep = FALSE)
deepWhether to make a deep clone.
pd_strat = PdStrategy$new() pd_strat$categorical_splitpd_strat = PdStrategy$new() pd_strat$categorical_split