## concordance_index()


Harrell's concordance index: discrimination of risk scores against observed survival.


Usage

``` python
concordance_index(
    surv,
    risk,
)
```


Computes Harrell's C-statistic, a measure of how well a risk score discriminates between subjects who experience early events and those who survive longer. The concordance index compares all comparable pairs of subjects: those with an observed event are compared to those still under observation at the same time or later. Higher risk should correspond to earlier failure; if predictions match reality better than chance, the index exceeds 0.5.

**Interpretation**:

- 0.5: Random discrimination (no better than a coin flip)
- 0.6-0.7: Moderate discrimination (clinically useful)
- 0.7-0.8: Strong discrimination
- 0.8+: Excellent discrimination (rare in practice)

**Practical use**: Validates a model's ability to rank subjects by risk. After fitting a Cox model or other survival model, compute the concordance index of its predictions to assess out-of-sample discrimination. A model with high concordance index generalizes well to ranking future subjects by risk.


## Parameters


`surv: Surv`  
A right-censored [Surv](Surv.md#greenwood.Surv) response (time-to-event data).

`risk: Any`  
Risk score for each subject, one per observation. Can be a 1-D array, Pandas/Polars series, or Python sequence. Higher values indicate higher risk (earlier expected failure). Examples: Cox model linear predictor, predicted log-hazard, or predicted cumulative incidence.


## Returns


`float`  
Concordance index between 0 and 1. Values above 0.5 indicate the model discriminates better than random; below 0.5 indicates worse-than-random discrimination (possibly inverted risk scale).


## Details

**Pair comparison rule**:

- A subject with an observed event at time t is compared to all subjects still under observation at time t or later (including censored subjects at exactly t).
- Pairs are concordant if the subject with the event has higher risk than the subject without.
- Pairs with tied risk scores are counted as 0.5 (half-concordant).
- Pairs with the same event time are excluded.

**Censoring handling**: Censored subjects are handled through the comparable pairs definition. A censored subject at time t can only be compared to subjects with events at times strictly greater than t. This avoids artificial inflation of concordance from censored subjects and matches R's `survival::concordance`.

**Relationship to other metrics**: The concordance index is related to the rank correlation between risk and observed survival. It's invariant to monotonic transformations of risk (e.g., \\\exp(\text{lp})\\ vs. \\\text{lp}\\ both give the same concordance).


## Examples

Fit a Cox model on the `lung` dataset and evaluate its discrimination. Higher linear predictor values should correspond to earlier deaths.


``` python
import greenwood as gw

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"]])

lp = cox.predict(type="lp")
c_index = gw.concordance_index(y, lp)
c_index
```


    0.6028530028979714


A concordance index of ~0.6 indicates moderate discrimination. Compare with baseline (naive model assuming all subjects are at equal risk):


``` python
import numpy as np
baseline_c = gw.concordance_index(y, np.zeros(len(y)))
print(f"Baseline: {baseline_c:.3f}")
print(f"Cox model: {c_index:.3f}")
print(f"Improvement: {c_index - baseline_c:.3f}")
```


    Baseline: 0.500
    Cox model: 0.603
    Improvement: 0.103


Evaluate on hold-out test data to assess generalization (use Cox model fit on training data, predict on test data):


``` python
# cox = CoxPH().fit(y_train, x_train)
# lp_test = cox.predict(x_test, type="lp")
# c_test = gw.concordance_index(y_test, lp_test)
```
