Elastic-net penalized Fine-Gray subdistribution hazard model.
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.
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.
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.
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.
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.