# PenalizedFineGray


Elastic-net penalized Fine-Gray subdistribution hazard model.


Usage

``` python
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](Surv.md#greenwood.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:


``` python
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) | Fit the penalized Fine-Gray model. |
| [predict()](#predict) | Predict linear predictor or risk from the penalized Fine-Gray model. |
| [predict_cumulative_incidence()](#predict_cumulative_incidence) | Predict cumulative incidence F(t \mid x) for new subjects. |
| [to_frame()](#to_frame) | Return the penalized coefficient table as a DataFrame. |

------------------------------------------------------------------------


### fit()


Fit the penalized Fine-Gray model.


Usage

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


#### Parameters


`surv: Surv | Outcome | str`  
A multi-state response: a [Surv](Surv.md#greenwood.Surv) with a categorical event, an [Outcome](Outcome.md#greenwood.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](Outcome.md#greenwood.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](Outcome.md#greenwood.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:


``` python
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

``` python
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

``` python
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

``` python
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`.
