## calibration()


Assess calibration of predicted survival probabilities at a fixed time.


Usage

``` python
calibration(
    surv,
    predicted,
    time,
    *,
    n_bins=10,
    conf_level=0.95,
    format=None,
)
```


Subjects are grouped into `n_bins` bins by their predicted survival probability at `time`. Within each bin the mean prediction is compared against the observed survival, a Kaplan-Meier estimate at `time` for that bin's subjects. A well-calibrated model has the observed values close to the predicted ones (points near the diagonal).


## Parameters


`surv: Surv`  
The [Surv](Surv.md#greenwood.Surv) response (right-censored or counting-process).

`predicted: Any`  
Predicted survival probability at `time`, one per subject (for example a column of `CoxPH.predict(newdata, type="survival", times=[time])`).

`time: float`  
The horizon at which predictions are assessed.

`n_bins: int = ``10`  
Number of prediction bins (default 10). Bins are quantile-based. Empty bins are dropped, so ties in `predicted` may yield fewer rows.

`conf_level: float = ``0.95`  
Confidence level for the observed (Kaplan-Meier) interval.

`format: str | None = None`  
Output format for the returned DataFrame: `None` (default), `"pandas"`, `"polars"`, or `"pyarrow"`. `None` (the default) will auto-detects and prefer Polars if available (falls back to Pandas, then Pyarrow, and raises an error if no DataFrame library is available).


## Returns


`DataFrame`  
One row per bin with columns `bin`, [n](Surv.md#greenwood.Surv.n), `predicted` (mean), `observed`, `observed_lower`, `observed_upper`. Format depends on the `format` parameter.


## Details

Bins are formed by splitting subjects into `n_bins` quantile-based groups of their predicted survival probability. Within each bin the Kaplan-Meier estimate at `time` gives the observed survival, and the mean of the predictions gives the predicted value. A well-calibrated model produces points that lie along the 45-degree diagonal when plotted as observed vs. predicted. Systematic departures from the diagonal indicate over- or under-prediction in that probability range.


## Examples

Fit a Cox model on the bundled `lung` dataset and assess calibration at one year. Each bin's mean predicted survival is compared against the observed Kaplan-Meier survival for that bin's subjects:


``` 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))
cox = gw.CoxPH().fit(y, lung[["age", "sex"]])

# Assess one-year calibration across five prediction bins
surv = cox.predict(lung[["age", "sex"]], type="survival", times=[365.0], format="pandas")
predicted = surv.iloc[0, 1:].to_numpy()
gw.calibration(y, predicted, 365.0, n_bins=5, format="polars")
```


shape: (5, 6)

| bin | n   | predicted | observed | observed_lower | observed_upper |
|-----|-----|-----------|----------|----------------|----------------|
| i64 | i64 | f64       | f64      | f64            | f64            |
| 1   | 45  | 0.275644  | 0.226515 | 0.12563        | 0.408414       |
| 2   | 44  | 0.325993  | 0.363082 | 0.237804       | 0.554357       |
| 3   | 45  | 0.388624  | 0.408116 | 0.284455       | 0.585537       |
| 4   | 45  | 0.485378  | 0.540004 | 0.395497       | 0.73731        |
| 5   | 49  | 0.568638  | 0.514285 | 0.376278       | 0.702909       |
