# RandomSurvivalForest


A random survival forest: a bagged ensemble of log-rank survival trees.


Usage

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


Each tree is grown on a bootstrap sample of the data and considers a random subset of covariates at every split, following Ishwaran et al. (2008). At each node the split threshold is chosen to maximize the log-rank separation between the child groups. Predictions average the per-tree cumulative-hazard functions across the ensemble; the scalar risk score is the summed ensemble cumulative hazard (mortality). Averaging many decorrelated trees yields a low-variance, well-calibrated non-parametric survival model that captures non-linearities and interactions without a proportional-hazards assumption.


## 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 = ``True`  
Whether to grow each tree on a bootstrap sample (required for `oob_score` and [variable_importance](GradientBoostingSurvivalAnalysis.md#greenwood.GradientBoostingSurvivalAnalysis.variable_importance)).

`oob_score: bool = ``False`  
Whether to compute an out-of-bag concordance estimate after fitting.

`engine: str = ``"numpy"`  
Compute backend for the split search: `"numpy"` (default, deterministic) or `"numba"` (faster on large datasets, requires the `fast` extra; produces a statistically equivalent fit that may differ in tie-breaking). `"auto"` uses Numba when available.

`random_state: Any = None`  
Seed or `numpy.random.Generator` for bootstrap sampling and per-node feature selection.


## Examples

Fit a forest on the bundled `lung` dataset and inspect the out-of-bag concordance:


``` python
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 the forest with an out-of-bag score
rsf = gw.RandomSurvivalForest(
    n_estimators=100, oob_score=True, random_state=0
).fit(y, lung[cols])
rsf
```


    RandomSurvivalForest (100 log-rank trees, max_features='sqrt')
    n = 213, events = 151, features = 5
    out-of-bag concordance = 0.6009
