PenalizedFineGray

Elastic-net penalized Fine-Gray subdistribution hazard model.

Usage

Source

PenalizedFineGray(
    cause,
    penalizer=0.1,
    l1_ratio=0.5,
    *,
    standardize=True,
    max_iter=1000,
    tol=1e-07,
)

Extends the Fine-Gray competing-risks regression with an elastic-net penalty \lambda\bigl(\alpha\|\beta\|_1 + \tfrac{1-\alpha}{2}\|\beta\|_2^2\bigr) on the subdistribution-hazard partial likelihood. This enables variable selection and coefficient shrinkage when the number of covariates is large relative to the number of target-cause events.

l1_ratio=1 is lasso (sparse), l1_ratio=0 is ridge (smooth shrinkage), and values in between blend the two. Covariates are standardized before penalizing (for fair penalty comparison across features) and coefficients are returned on the original scale. Because coefficients are biased by design, the model reports point estimates but not standard errors or p-values.

Parameters

cause: Any

The target cause-of-interest label from the multi-state Surv response.

penalizer: float = 0.1

Overall penalty strength (\lambda). 0 recovers the unpenalized Fine-Gray fit.

l1_ratio: float = 0.5

Elastic-net mixing in [0, 1]: 1 is lasso, 0 is ridge.

standardize: bool = True

Standardize covariates to unit variance before penalizing (default True).

max_iter: int = 1000

Maximum FISTA iterations and the relative-change convergence tolerance.

tol: int = 1000
Maximum FISTA iterations and the relative-change convergence tolerance.

Examples

Fit a lasso-penalized Fine-Gray model on the mgus2 competing-risks data:

import greenwood as gw

mg = gw.load_dataset("mgus2", backend="pandas")
cr = gw.Outcome.first_event(
    endpoints={"pcm": ("ptime", "pstat"), "death": ("futime", "death")}
)

pfg = gw.PenalizedFineGray(cause="pcm", penalizer=0.01, l1_ratio=1.0)
pfg.fit(cr, covariates=["age", "sex"], data=mg)
pfg
PenalizedFineGray (elastic-net Fine-Gray, cause='pcm', penalizer=0.01, l1_ratio=1.0)

           coef
age   -0.008028
sexM  -0.002464

n = 1384, events = 115, nonzero coefficients = 2

Methods

Name Description
fit() Fit the penalized Fine-Gray model.
predict() Predict linear predictor or risk from the penalized Fine-Gray model.
predict_cumulative_incidence() Predict cumulative incidence F(t \mid x) for new subjects.
to_frame() Return the penalized coefficient table as a DataFrame.

fit()

Fit the penalized Fine-Gray model.

Usage

Source

fit(
    surv,
    covariates=None,
    *,
    data=None,
)

Parameters

surv: Surv | Outcome | str

A multi-state response: a Surv with a categorical event, an Outcome (such as gw.Outcome.first_event(...)), or a formula string such as "Surv(etime, factor(cause, c(0, 1, 2), c('censor', 'pcm', 'death'))) ~ age + sex". An Outcome or formula reads its columns from data. The formula’s right-hand side sets covariates.

covariates: Any = None

A dataframe or 2-D array of covariates. 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

PenalizedFineGray
The fitted estimator with penalized coefficients in coef_.

Examples

Fit a lasso-penalized Fine-Gray model on the mgus2 competing-risks data. With l1_ratio=1.0 (pure lasso), some coefficients are driven to exactly zero:

import greenwood as gw

mg = gw.load_dataset("mgus2", backend="pandas")
cr = gw.Outcome.first_event(
    endpoints={"pcm": ("ptime", "pstat"), "death": ("futime", "death")}
)

pfg = gw.PenalizedFineGray(
    cause="pcm", penalizer=0.1, l1_ratio=1.0
).fit(cr, covariates=["age", "sex"], data=mg)
pfg
PenalizedFineGray (elastic-net Fine-Gray, cause='pcm', penalizer=0.1, l1_ratio=1.0)

      coef
age     -0
sexM    -0

n = 1384, events = 115, nonzero coefficients = 0

predict()

Predict linear predictor or risk from the penalized Fine-Gray model.

Usage

Source

predict(
    newdata=None,
    *,
    type="lp",
    format=None,
)

Parameters

newdata: Any = None

Covariate values for prediction. If None, uses the training data. 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.

type: str = "lp"

"lp" (default) or "risk" (\exp(\text{lp})).

format: str | None = None
Ignored (present for API consistency).

Returns

ndarray
Array of shape (n_subjects,).

predict_cumulative_incidence()

Predict cumulative incidence F(t \mid x) for new subjects.

Usage

Source

predict_cumulative_incidence(
    newdata=None,
    *,
    times=None,
    format=None,
)

Parameters

newdata: Any = None

Covariate values. If None, uses the training data. 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 CIF. If None, uses the target-event times from the training data.

format: str | None = None
Output format: None, "pandas", "polars", or "pyarrow".

Returns

DataFrame
A table with a time column and one subject_N column per subject.

to_frame()

Return the penalized coefficient table as a DataFrame.

Usage

Source

to_frame(
    *,
    format=None,
)

Parameters

format: str | None = None
Output format: None (default), "pandas", "polars", or "pyarrow".

Returns

DataFrame
A tidy table with columns term, estimate, and hazard_ratio.