Package 'randomPlantedForest'

Title: Random Planted Forest: A Directly Interpretable Tree Ensemble
Description: An implementation of the Random Planted Forest algorithm for directly interpretable tree ensembles based on a functional ANOVA decomposition.
Authors: Joseph Theo Meyer [aut], Munir Hiabu [aut], Maike Spankus [aut], Marvin N. Wright [aut], Lukas Burk [cre, aut] (ORCID: <https://orcid.org/0000-0001-7528-3795>)
Maintainer: Lukas Burk <[email protected]>
License: Apache License (>= 2)
Version: 0.3.0
Built: 2026-07-13 21:43:45 UTC
Source: https://github.com/PlantedML/randomPlantedForest

Help Index


Extract predicted components from a Random Planted Forest

Description

Prediction components are a functional decomposition of the model prediction. The sum of all components equals the overall predicted value for an observation.

Usage

predict_components(object, new_data, max_interaction = NULL, predictors = NULL)

Arguments

object

A fit object of class rpf.

new_data

Data for new observations to predict.

max_interaction

integer or NULL: Maximum degree of interactions to consider. Default will use the max_interaction parameter from the rpf object. Must be between 1 (main effects only) and the max_interaction of the rpf object.

predictors

character or NULL: Vector of one or more column names of predictor variables in new_data to extract components for. If NULL, all variables and their interactions are returned.

Details

Extracts all possible components up to max_interaction degrees, up to the value set when calling rpf(). The intercept is always included. Optionally predictors can be specified to only include components including the given variables. If max_interaction is greater than length(predictors), the max_interaction will be lowered accordingly.

Value

A list with elements:

  • m (data.table): Components for each main effect and interaction term, representing the functional decomposition of the prediction. All components together with the intercept sum up to the prediction. For multiclass classification, the number of output columns is multiplied by the number of levels in the outcome.

  • intercept (numeric(1)): Expected value of the prediction.

  • x (data.table): Copy of new_data containing predictors selected by predictors.

  • target_levels (character): For multiclass classification only: Vector of target levels which can be used to disassemble m, as names include both term and target level.

Note

Depending on the number of predictors and max_interaction, the number of components will increase drastically to sum(choose(ncol(new_data), seq_len(max_interaction))).

Examples

# Regression task, only some predictors
train <-  mtcars[1:20, 1:4]
test <-  mtcars[21:32, 1:4]

set.seed(23)
rpfit <- rpf(mpg ~ ., data = train, max_interaction = 3, ntrees = 30)

# Extract all components, including main effects and interaction terms up to `max_interaction`
(components <- predict_components(rpfit, test))

# sums to prediction
cbind(
  m_sum = rowSums(components$m) + components$intercept,
  prediction = predict(rpfit, test)
)

# Only get components with interactions of a lower degree, ignoring 3-way interactions
predict_components(rpfit, test, max_interaction = 2)

# Only retrieve main effects
(main_effects <- predict_components(rpfit, test, max_interaction = 1))

# The difference is the combined contribution of interaction effects
cbind(
  m_sum = rowSums(main_effects$m) + main_effects$intercept,
  prediction = predict(rpfit, test)
)

Random Planted Forest Predictions

Description

Random Planted Forest Predictions

Usage

## S3 method for class 'rpf'
predict(
  object,
  new_data,
  type = ifelse(object$mode == "regression", "numeric", "prob"),
  ...
)

Arguments

object

A fit object of class rpf.

new_data

Data for new observations to predict.

type

"numeric" for regression outcomes, "class" for class predictions or "prob" for probability predictions.

For classification and loss = "L1" or "L2", "numeric" yields raw predictions which are not guaranteed to be valid probabilities in ⁠[0, 1]⁠. For type = "prob", these are truncated to ensure this property.

If loss is "logit" or "exponential", type = "link" is an alias for type = "numeric", as in this case the raw predictions have the additional interpretation similar to the linear predictor in a glm.

...

Unused.

Value

For regression: A tbl with column .pred with the same number of rows as new_data.

For classification: A tbl with one column for each level in y containing class probabilities if type = "prob". For type = "class", one column .pred with class predictions is returned. For type = "numeric" or "link", one column .pred with raw predictions.

Examples

# Regression with L2 loss
rpfit <- rpf(y = mtcars$mpg, x = mtcars[, c("cyl", "wt")])
predict(rpfit, mtcars[, c("cyl", "wt")])

Preprocess predictors for prediction

Description

Convert logical and character columns to appropriate types, re-order factor levels to match the ordering learned during fitting (stored in object$factor_levels), re-encode factor columns as integers, and return a numeric matrix suitable for the underlying C++ prediction routines.

Usage

preprocess_predictors_predict(object, predictors)

Arguments

object

An object of class rpf returned by rpf().

predictors

A data frame or matrix of predictor values to preprocess.

Details

This is primarily an internal utility used by predict() methods but is exported to support advanced users and tests.

Value

A numeric matrix with the same number of rows as predictors.

Examples

rpfit <- rpf(x = mtcars[, c("cyl", "wt")], y = mtcars$mpg)
processed <- hardhat::forge(mtcars[, c("cyl", "wt")], rpfit$blueprint)
X <- preprocess_predictors_predict(rpfit, processed$predictors)
dim(X)

Print an rpf fit

Description

Print an rpf fit

Usage

## S3 method for class 'rpf'
print(x, ...)

Arguments

x

And object of class rpf.

...

Further arguments passed to or from other methods.

Value

Invisibly: x.

See Also

rpf.

Examples

rpf(mpg ~ cyl + wt + drat, data = mtcars, max_interaction = 2, ntrees = 10)

Compact printing of forest structures

Description

These methods are provided to avoid flooding the console with long nested lists containing tree structures. Note

Usage

## S3 method for class 'rpf_forest'
print(x, ...)

## S3 method for class 'rpf_forest'
str(object, ...)

Arguments

x

Object of class rpf_forest

...

Further arguments passed to or from other methods.

object

Object of class rpf_forest

See Also

rpf

Examples

rpfit <- rpf(mpg ~ cyl + wt, data = mtcars, ntrees = 10)
print(rpfit$forest)
str(rpfit$forest)

Purify a Random Planted Forest

Description

Purifies an rpf object.

Usage

purify(x, ...)

## Default S3 method:
purify(x, ...)

## S3 method for class 'rpf'
purify(x, ..., maxp_interaction = NULL, mode = 2L, nthreads = NULL)

is_purified(x)

Arguments

x

And object of class rpf.

...

(Unused)

maxp_interaction

integer or NULL: Only compute/store purified components up to this interaction order. Higher-order purified trees are zeroed (not computed) but still implicitly influence lower orders during purification. If NULL, purify all orders (default behavior).

mode

integer(1): Purification algorithm mode. 1 = legacy grid path used by fit$fit$purify(); 2 = fast exact KD-tree based path. Defaults to 2.

nthreads

integer or NULL: number of threads to use. If NULL, defaults to min of the object's configured nthreads and available threads.

Details

Unless rpf() is called with purify = TRUE, the forest has to be purified after fit to ensure the components extracted by predict_components() are valid. predict_components() will automatically purify a forest if is_purified() reports FALSE.

Value

Invisibly: The rpf object.

Examples

rpfit <- rpf(mpg ~., data = mtcars, max_interaction = 2, ntrees = 10)
purify(rpfit)

Random Planted Forest

Description

Random Planted Forest

Usage

rpf(x, ...)

## S3 method for class 'data.frame'
rpf(
  x,
  y,
  max_interaction = 1,
  ntrees = 50,
  splits = 30,
  split_try = 10,
  t_try = 0.4,
  split_decay_rate = 0.1,
  max_candidates = 50,
  delete_leaves = TRUE,
  deterministic = FALSE,
  nthreads = 1,
  purify = FALSE,
  cv = FALSE,
  loss = "L2",
  delta = 0,
  epsilon = 0.1,
  split_structure = "leaves",
  export_forest = FALSE,
  ...
)

## S3 method for class 'matrix'
rpf(
  x,
  y,
  max_interaction = 1,
  ntrees = 50,
  splits = 30,
  split_try = 10,
  t_try = 0.4,
  split_decay_rate = 0.1,
  max_candidates = 50,
  delete_leaves = TRUE,
  deterministic = FALSE,
  nthreads = 1,
  purify = FALSE,
  cv = FALSE,
  loss = "L2",
  delta = 0,
  epsilon = 0.1,
  split_structure = "leaves",
  export_forest = FALSE,
  ...
)

## S3 method for class 'formula'
rpf(
  formula,
  data,
  max_interaction = 1,
  ntrees = 50,
  splits = 30,
  split_try = 10,
  t_try = 0.4,
  split_decay_rate = 0.1,
  max_candidates = 50,
  delete_leaves = TRUE,
  deterministic = FALSE,
  nthreads = 1,
  purify = FALSE,
  cv = FALSE,
  loss = "L2",
  delta = 0,
  epsilon = 0.1,
  split_structure = "leaves",
  export_forest = FALSE,
  ...
)

## S3 method for class 'recipe'
rpf(
  x,
  data,
  max_interaction = 1,
  ntrees = 50,
  splits = 30,
  split_try = 10,
  t_try = 0.4,
  split_decay_rate = 0.1,
  max_candidates = 50,
  delete_leaves = TRUE,
  deterministic = FALSE,
  nthreads = 1,
  purify = FALSE,
  cv = FALSE,
  loss = "L2",
  delta = 0,
  epsilon = 0.1,
  split_structure = "leaves",
  export_forest = FALSE,
  ...
)

Arguments

x, data

Feature matrix, or data.frame, or recipe.

...

(Unused).

y

Target vector for use with x. The class of y (either numeric or factor) determines if regression or classification will be performed.

max_interaction

⁠[1]⁠: Maximum level of interaction determining maximum number of split dimensions for a tree. The default 1 corresponds to main effects only. If 0, the number fo columns in x is used, i.e. for 10 predictors, this is equivalent to setting max_interaction = 10.

ntrees

⁠[50]⁠: Number of trees generated per family.

splits

⁠[30]⁠: Number of splits performed for each tree family.

split_try

⁠[10]⁠: Number of split points to be considered when choosing a split candidate.

t_try

⁠[0.4]⁠: A value in (0,1] specifying the proportion of viable split-candidates in each round.

split_decay_rate

⁠[0.1]⁠: Exponential decay factor for aging split-candidates. Possible splits are initiated with age=0. Whenever a possible split becomes a split_candidate (i.e. it has been drawn when drawing max(max_candidates , t_try * possible options ) times) it ages by +1. The age of the single split-candidate with minimal loss is reset to zero. Split_candidates are sampled from Possible_splits with weight exp(-split_decay_rate_ * age). A high split_decay_rate means faster aging. split_decay_rate=0 results in no aging and uniform sampling.

max_candidates

⁠[50]⁠: Maximum number of split-candidates sampled per iteration. Number of split_candidates in each round is given by max(max_candidates , t_try * possible options).

delete_leaves

⁠[TRUE]⁠: Whether to delete a parent leaf when splitting along an existing dimension.

deterministic

⁠[FALSE]⁠: Choose whether approach deterministic or random.

nthreads

⁠[1L]⁠: Number of threads used for computation, defaulting to serial execution.

purify

⁠[FALSE]⁠: Whether the forest should be purified. Set to TRUE to enable components extract with predict_components() are valid. Can be achieved after fitting with purify().

cv

⁠[FALSE]⁠: Determines if cross validation is performed.

loss

⁠["L2"]⁠: For regression, only "L2" is supported. For classification, "L1", "logit" and "exponential" are also available. "exponential" yields similar results as "logit" while being significantly faster.

delta

⁠[0]⁠: Only used if loss is "logit" or "exponential". Proportion of class membership is truncated to be smaller 1-delta when calculating the loss to determine the optimal split.

epsilon

⁠[0.1]⁠: Only used if loss = "logit" or "exponential". Proportion of class membership is truncated to be smaller 1-epsilon when calculating the fit in a leaf.

split_structure

⁠["leaves"]⁠: Defines the structure of a possible split and how to choose split_candidates. Can be one of "leaves", "hist", "cur_trees_1", "cur_trees_2", or "res_trees". Further details are given below.

export_forest

⁠[FALSE]⁠: Whether to store the flattened forest in the returned object as ⁠$forest⁠. If FALSE, ⁠$forest⁠ is NULL, reducing memory use of the returned object.

formula

Formula specification, e.g. y ~ x1 + x2.

Details

splits

The number of splits is the main tuning parameter affecting the accuracy of predictions.

split_structure

The split_structure argument controls how split candidates are constructed and sampled. In each round, a t_try fraction (capped by max_candidates) is drawn from the pool of all possible splits with weights exp(-split_decay_rate * age).

leaves

Split candidates are (leaf, split-dimension) pairs. For each sampled candidate, split_try thresholds are drawn uniformly from the valid range within that leaf and evaluated to choose the best split.

cur_trees_1

Split candidates are (current-tree, split-dimension) pairs. For each sampled candidate, perform split_try evaluations. Each evaluation samples a leaf from the set of valid current trees (with probability proportional to its number of available thresholds) and then uniformly samples a single threshold within that leaf.

cur_trees_2

Split candidates are (current-tree, split-dimension) pairs. For each sampled candidate, iterate through every valid leaf. Within each leaf, sample split_try thresholds uniformly and evaluate them.

res_trees

Split candidates are resulting trees. For each sampled candidate, run split_try evaluations by sampling a (split-dimension, leaf) pair from all valid pairs (with probability proportional to its number of available thresholds), then uniformly sampling one threshold within that pair.

Value

Object of class "rpf" with model object contained in ⁠$fit⁠.

Examples

# Regression with x and y
rpfit <- rpf(x = mtcars[, c("cyl", "wt")], y = mtcars$mpg)

# Regression with formula
rpfit <- rpf(mpg ~ cyl + wt, data = mtcars)