ExtraSurvivalTrees

An extremely-randomized survival forest (extra survival trees).

Usage

Source

ExtraSurvivalTrees(
    *,
    n_estimators=100,
    max_depth=None,
    min_samples_split=6,
    min_samples_leaf=3,
    max_features="sqrt",
    bootstrap=False,
    oob_score=False,
    engine="numpy",
    random_state=None,
)

Like RandomSurvivalForest, but at each node the split threshold for every candidate covariate is drawn at random (uniformly between the covariate’s minimum and maximum at that node) rather than optimized. The extra randomization further decorrelates the trees, often lowering variance and speeding up fitting at the cost of a little bias. Following the extra-trees convention, each tree is grown on the full sample (bootstrap=False) by default; set bootstrap=True to enable out-of-bag scoring and permutation variable importance.

Parameters

n_estimators: int = 100

Number of trees in the forest.

max_depth: int | None = None

Maximum depth of each tree (None for unlimited).

min_samples_split: int = 6

Minimum node size eligible for splitting.

min_samples_leaf: int = 3

Minimum subjects in each child of a split.

max_features: Any = "sqrt"

Covariates considered per split: "sqrt" (default), "log2", an int, a float, or None.

bootstrap: bool = False

Whether to grow each tree on a bootstrap sample. False by default (the extra-trees convention); required to be True for oob_score and variable_importance.

oob_score: bool = False

Whether to compute an out-of-bag concordance estimate after fitting (requires bootstrap=True).

engine: str = "numpy"

Compute backend for the split search: "numpy" (default, deterministic) or "numba" (faster on large datasets, requires the fast extra). "auto" uses Numba when available.

random_state: Any = None
Seed or numpy.random.Generator for split randomization and per-node feature selection.

Examples

Fit extra survival trees on the bundled lung dataset:

import greenwood as gw

# Load data and build a right-censored response
lung = gw.load_dataset("lung", backend="pandas").dropna(subset=["ph.ecog", "ph.karno"])
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
cols = ["age", "sex", "ph.ecog", "ph.karno", "wt.loss"]

# Fit with bootstrap sampling so an out-of-bag score is available
ext = gw.ExtraSurvivalTrees(
    n_estimators=100, bootstrap=True, oob_score=True, random_state=0
).fit(y, lung[cols])
ext
ExtraSurvivalTrees (100 log-rank trees, max_features='sqrt')
n = 213, events = 151, features = 5
out-of-bag concordance = 0.6124