## CoxNetCVResult


Result of cross-validated penalizer selection for [CoxNet](CoxNet.md#greenwood.CoxNet).


Usage

``` python
CoxNetCVResult(
    penalizers, mean_scores, std_scores, n_nonzero, metric, l1_ratio, k
)
```


Returned by [cv_coxnet()](cv_coxnet.md#greenwood.cv_coxnet). Stores the cross-validation scores at every tested penalizer value, identifies the best penalizer (highest concordance or lowest Brier score), and applies the *one-standard-error rule* for a more parsimonious alternative.

Penalizers are ordered from *largest* (most regularized, sparsest model) to *smallest* (least regularized, densest model).


## Attributes


`penalizers_`  
Penalizer values tested, sorted descending.

`mean_scores_`  
Mean cross-validation score at each penalizer.

`std_scores_`  
Standard deviation of per-fold scores at each penalizer.

`n_nonzero_`  
Average number of non-zero coefficients at each penalizer (averaged over cross-validation folds).

`metric_`  
Metric used: `"concordance"` or `"brier"`.

`l1_ratio_`  
Elastic-net mixing parameter fixed during the path search.

`k_`  
Number of folds used.

`best_penalizer_`  
Penalizer with the best mean cross-validation score.

`best_score_`  
Mean score at `best_penalizer_`.

`penalizer_1se_`  
Largest penalizer (most regularized) whose mean score is within one standard error of `best_score_`. Prefer this when parsimony matters.

`score_1se_`  
Mean score at `penalizer_1se_`.


## Examples

Run cross-validated penalizer selection and inspect the result:


``` python
import greenwood as gw

# Load data and build a right-censored response
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
cols = ["age", "sex", "ph.ecog", "ph.karno", "wt.loss"]

# Run cross-validated penalizer selection
cv_result = gw.cv_coxnet(y, lung[cols], seed=23)
cv_result
```


    CoxNetCV (concordance, ↑ higher is better, l1_ratio=1.0, 5-fold)

      best penalizer : 0.10767  (mean concordance: 0.6356)
      1-SE  penalizer : 0.16435  (mean concordance: 0.6205)

      50 penalizers tested, range [0.000218, 0.218]


The best penalizer and the more conservative one-standard-error penalizer are available as attributes:


``` python
# Retrieve the best penalizer value
cv_result.best_penalizer_
```


    0.10767101882396805


``` python
# Retrieve the more conservative one-standard-error penalizer
cv_result.penalizer_1se_
```


    0.16435097767696763


## Methods

| Name | Description |
|----|----|
| [to_frame()](#to_frame) | Return the CV path as a tidy DataFrame, one row per penalizer. |

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


#### to_frame()


Return the CV path as a tidy DataFrame, one row per penalizer.


Usage

``` python
to_frame(*, format=None)
```


##### Parameters


`format: str | None = None`  
Output format: `None` (default), `"pandas"`, `"polars"`, or `"pyarrow"`. When `None`, a backend is auto-detected.


##### Returns


`DataFrame`  
Columns: `penalizer`, `mean_score`, `std_score`, `n_nonzero`. Rows are ordered from largest to smallest penalizer.


##### Examples

Export the full CV path as a Polars DataFrame for plotting or further analysis:


``` python
import greenwood as gw

# Load data and run cross-validated penalizer selection
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
cols = ["age", "sex", "ph.ecog", "ph.karno", "wt.loss"]
result = gw.cv_coxnet(y, lung[cols], seed=23)

# Export the CV path as a Polars DataFrame
result.to_frame(format="polars")
```


shape: (50, 4)

| penalizer | mean_score | std_score | n_nonzero |
|-----------|------------|-----------|-----------|
| f64       | f64        | f64       | f64       |
| 0.217882  | 0.533798   | 0.032417  | 0.6       |
| 0.189233  | 0.592456   | 0.044763  | 1.2       |
| 0.164351  | 0.620501   | 0.050398  | 1.8       |
| 0.142741  | 0.629349   | 0.041546  | 2.0       |
| 0.123972  | 0.629349   | 0.041546  | 2.0       |
| …         | …          | …         | …         |
| 0.000383  | 0.618034   | 0.036494  | 5.0       |
| 0.000333  | 0.618034   | 0.036494  | 5.0       |
| 0.000289  | 0.618034   | 0.036494  | 5.0       |
| 0.000251  | 0.618034   | 0.036494  | 5.0       |
| 0.000218  | 0.618034   | 0.036494  | 5.0       |
