Skip to contents

Grow an ensemble of greedy concentration-index trees. Each tree uses the same greedy tree builder as ci_tree() on a perturbed sample of the training data, so the split at each node is chosen by directly maximizing concentration-index gain over candidate variables and split points. The optional mtry control randomly samples candidate variables at each node inside the greedy split search.

cf_ci() is kept for existing code. New code should use ci_forest(), because the current forest is an ensemble of greedy concentration-index trees rather than a conditional-inference forest.

Usage

ci_forest(
  formula,
  data,
  rank_name,
  outcome_name,
  weights = NULL,
  type = c("CI", "CIg", "CIc", "L"),
  control = ci_tree_control(),
  ntree = 500L,
  mtry = NULL,
  perturb = list(replace = FALSE, fraction = 0.632),
  parallel = FALSE,
  future.seed = TRUE,
  na.action = stats::na.omit,
  ...
)

cf_ci(...)

Arguments

formula

A model formula, typically with a two-column response such as cbind(rank, outcome) ~ x1 + x2.

data

A data frame containing the variables in formula.

rank_name

Name of the socioeconomic rank variable.

outcome_name

Name of the outcome variable.

weights

Optional non-negative case weights.

type

One of "CI", "CIg", "CIc", or "L" selecting the inequality index used for split scoring. "L" uses observed socioeconomic levels in the first response column rather than fractional ranks.

control

A control object created by ci_tree_control(). Objects from partykit::ctree_control() are accepted for their shared controls, but conditional-inference test controls such as mincriterion are ignored by the greedy tree builder.

ntree

Number of trees to grow.

mtry

Optional number of variables randomly tried at each split.

perturb

Resampling specification. Use NULL for the default subsample or a list with optional replace and fraction entries. replace controls whether rows are sampled with replacement and must be NULL or a single non-missing logical. fraction controls the sample size relative to the complete analysis data and must be NULL or a positive finite number.

parallel

Logical; grow trees with future.apply::future_lapply(). This requires the suggested package future.apply. The future backend is controlled by the user outside ci_forest(), for example with future::plan().

future.seed

Passed to future.apply::future_lapply() when parallel = TRUE.

na.action

A function for handling missing values.

...

Currently ignored; retained for backwards compatibility.

Value

A fitted ci_forest object containing the greedy trees, in-bag indicators, fitted values, and forest controls.

A fitted ci_forest object.

Details

ci_forest() is an ensemble of greedy CI trees, not a conditional-inference forest. Randomness enters through row perturbation and, optionally, through mtry, which restricts the number of predictors searched at each node. Within each tree, the split rule is the same direct maximization of concentration-index gain used by ci_tree(). Predictions are aggregated across trees by averaging terminal-node summaries. The fitted object retains the member trees in object$trees; model-selection helpers use those internal tree partitions to compute forest-native validation gain.

References

Breiman L (2001). "Random Forests." Machine Learning, 45, 5-32.

Breiman L, Friedman JH, Olshen RA, Stone CJ (1984). Classification and Regression Trees. Wadsworth.

Hothorn T, Zeileis A (2015). "partykit: A Modular Toolkit for Recursive Partytioning in R." Journal of Machine Learning Research, 16, 3905-3909. https://jmlr.org/papers/v16/hothorn15a.html.

Examples

if (requireNamespace("future", quietly = TRUE) &&
    requireNamespace("future.apply", quietly = TRUE)) {
  old_plan <- future::plan()
  on.exit(future::plan(old_plan), add = TRUE)
  future::plan(future::sequential)

  fit <- ci_forest(
    cbind(rank, outcome) ~ income,
    data = data.frame(
      rank = c(10, 20, 30, 40, 50, 60),
      outcome = c(1, 0, 1, 0, 1, 1),
      income = c(2, 4, 6, 8, 10, 12)
    ),
    rank_name = "rank",
    outcome_name = "outcome",
    ntree = 3,
    parallel = TRUE,
    control = ci_tree_control(minsplit = 1, minbucket = 1, maxdepth = 1)
  )

  nrow(stats::fitted(fit))
}
#> [1] 6