Gradient-boosted cumulative incidence model for competing risks.
SurvivalBoost(
*,
n_estimators=100,
learning_rate=0.05,
max_depth=3,
min_samples_leaf=10,
subsample=1.0,
max_features=None,
n_time_grid_steps=100,
hard_zero_fraction=0.1,
n_horizons_per_observation=3,
epsilon_censoring=0.05,
random_state=None,
)
Builds an ensemble of regression trees that estimates the cause-specific cumulative incidence functions (CIFs) and the any-event survival function via multi-class softmax gradient boosting. At each boosting iteration, random time horizons are sampled and concatenated as an extra input feature. IPCW weights correct for right censoring. The result is a flexible, nonparametric competing-risks model that learns CIFs directly from the data.
Parameters
n_estimators: int = 100
-
Number of boosting iterations. Each iteration fits one tree per class (event type + survival).
learning_rate: float = 0.05
-
Shrinkage applied to each tree’s contribution.
max_depth: int = 3
-
Maximum depth of each regression tree.
min_samples_leaf: int = 10
-
Minimum number of samples required in each leaf.
subsample: float = 1.0
-
Fraction of the training rows sampled (without replacement) per iteration.
max_features: Any = None
-
Features considered per split: None (all), "sqrt", "log2", an int, or a float.
n_time_grid_steps: int = 100
-
Number of time points in the default prediction grid. The grid is built from quantiles of observed event times.
hard_zero_fraction: float = 0.1
-
Fraction of sampled time horizons forced to zero at each iteration, ensuring the model learns zero incidence at t = 0.
n_horizons_per_observation: int = 3
-
Number of independent time horizons sampled per subject at each iteration. Higher values give more stable gradients at the cost of larger per-iteration datasets.
epsilon_censoring: float = 0.05
-
Floor for censoring survival probabilities to prevent extreme IPCW weights.
random_state: Any = None
-
Seed or
numpy.random.Generator for reproducibility.
Examples
Fit to synthetic competing-risks data and predict cumulative incidence:
import greenwood as gw
sim = gw.simulate_competing_risks(n=500, n_causes=2, n_covariates=3, seed=42)
sb = gw.SurvivalBoost(n_estimators=50, learning_rate=0.1, max_depth=3, random_state=0)
sb.fit(sim.surv, covariates=sim.covariates)
sb
SurvivalBoost (50 rounds, learning_rate=0.1, max_depth=3)
n = 500, events = 296, causes = 2, features = 3
# Predict survival and CIFs at specific times
import numpy as np
times = np.array([2.0, 5.0, 10.0])
cif = sb.predict_cumulative_incidence(sim.covariates, times=times)
cif.shape # (n_subjects, n_events, n_times)
# Survival function
surv = sb.predict_survival_function(sim.covariates, times=times)
surv.shape # (n_subjects, n_times)
Methods
fit()
Fit the gradient-boosted cumulative incidence model.
fit(
surv,
covariates=None,
*,
data=None,
)
Parameters
surv: Surv | Outcome | str
-
A multi-state Surv response, built with gw.Surv() and a categorical event. An Outcome or a formula string such as "Surv(time, factor(cause, c(0, 1, 2), c('censor', 'pcm', 'death'))) ~ age" is also accepted, with its columns read from data. The right-hand side sets covariates.
covariates: Any = None
-
A dataframe, a 2-D array, or a right-hand-side formula string evaluated against data. A list of column names in data also works.
data: Any = None
-
A data frame (pandas, Polars, PyArrow, DuckDB, a lazy frame, …) holding the columns named by the response and
covariates. When surv is an Outcome or a formula, rows with a missing value in any column used are dropped before fitting. Covariate formula strings and lists of column names are also resolved here.
Returns
self
-
The fitted estimator.
Examples
Fit a boosted CIF model to synthetic competing-risks data and inspect the result. The model learns a separate tree per class at each round:
import greenwood as gw
sim = gw.simulate_competing_risks(
n=500, n_causes=2, n_covariates=3, seed=42
)
sb = gw.SurvivalBoost(
n_estimators=50, learning_rate=0.1, max_depth=3, random_state=0
).fit(sim.surv, covariates=sim.covariates)
sb
SurvivalBoost (50 rounds, learning_rate=0.1, max_depth=3)
n = 500, events = 296, causes = 2, features = 3
predict_cumulative_incidence()
Predict cause-specific cumulative incidence functions.
predict_cumulative_incidence(
newdata=None,
*,
times=None,
format=None,
)
Parameters
newdata: Any = None
-
Covariates for prediction. A dataframe, 2-D array, or formula string. None is not supported (training covariates are not cached). A data frame may also hold other columns. The covariates are picked out by name and coded as they were at fit time, so the frame the model was fit on can be passed as is.
times: Any = None
-
Time points at which to evaluate the CIFs. Defaults to the training-time grid.
format: str | None = None
-
When
None, returns a 3-D NumPy array of shape (n_subjects, n_events, n_times). Event index 0 is the survival probability (complement of all CIFs). Indices 1..K correspond to cause-specific CIFs. When a DataFrame backend name is given (e.g., "polars"), returns a long-format table with columns time, cause, subject, and probability.
Returns
numpy.ndarray or DataFrame
-
A 3-D array or a long-format DataFrame.
predict_proba()
Predict class probabilities at a single time horizon.
predict_proba(
newdata,
*,
time_horizon,
)
Returns an array of shape (n_subjects, n_classes) where column 0 is the probability of remaining event-free and columns 1..K are cause-specific CIFs at time_horizon.
Parameters
newdata: Any
-
Covariates for prediction. A data frame may also hold other columns. The covariates are picked out by name and coded as they were at fit time, so the frame the model was fit on can be passed as is.
time_horizon: float
-
The time at which to evaluate probabilities.
Returns
numpy.ndarray
-
Probabilities of shape
(n_subjects, n_classes).
predict_survival_function()
Predict the any-event survival function.
predict_survival_function(
newdata=None,
*,
times=None,
format=None,
)
Parameters
newdata: Any = None
-
Covariates for prediction. A data frame may also hold other columns. The covariates are picked out by name and coded as they were at fit time, so the frame the model was fit on can be passed as is.
times: Any = None
-
Time points at which to evaluate. Defaults to the training-time grid.
format: str | None = None
-
DataFrame backend for output.
None returns a 2-D NumPy array of shape (n_subjects, n_times).
Returns
numpy.ndarray or DataFrame
-
Survival probabilities.