domains / science / survival-analysis / scikit-survival

scikit-survival

Skill card

combined

The K-Dense-AI copy is the most rigorous, providing a strict, leakage-safe workflow, pinned dependencies, and specific constraints (e.g., IPCW metrics must use training data for censoring distributions, and evaluation times must be restricted to the training support). The other three copies (Vibe-Skills, medical-research-skills, OpenClaw-Medical-Skills) are nearly identical to each other and provide a broader, more introductory overview with a model selection decision tree and a complete runnable example using a built-in dataset. However, they lack the strict procedural safeguards found in the K-Dense copy. Because the K-Dense copy is a specialized, high-integrity procedure while the others are general guides that lack these critical constraints, crowning one would hide the alternative approach. A combined skill should use the K-Dense workflow as the core procedure but include the model selection heuristics and the runnable example from the other copies.

Repositories

RepositoryPath
K-Dense-AI/scientific-agent-skillsskills/scikit-survival/SKILL.md
foryourhealth111-pixel/Vibe-Skillsbundled/skills/scikit-survival/SKILL.md
aipoch/medical-research-skillsscientific-skills/Data Analysis/scikit-survival/SKILL.md
FreedomIntelligence/OpenClaw-Medical-Skillsskills/scikit-survival/SKILL.md

Other copies

RoleRepositoryPath
peerK-Dense-AI/scientific-agent-skillsskills/scikit-survival/SKILL.md
peerforyourhealth111-pixel/Vibe-Skillsbundled/skills/scikit-survival/SKILL.md
peeraipoch/medical-research-skillsscientific-skills/Data Analysis/scikit-survival/SKILL.md
peerFreedomIntelligence/OpenClaw-Medical-Skillsskills/scikit-survival/SKILL.md

Combined skill

---
name: scikit-survival
description: Builds, evaluates, and audits right-censored or competing-risk survival workflows with scikit-survival, including leakage-safe preprocessing, model selection, probability prediction, and censoring-aware metrics.
license: MIT
compatibility: Requires Python 3.11+, uv, and the pinned scikit-survival 0.28.0 stack for executable examples.
---

# scikit-survival

## Scope
Use this skill for scikit-survival 0.28.0 workflows involving right-censored structured outcomes, Cox PH, Coxnet, IPC ridge, survival trees, forests, boosting, and SVMs. It covers discrimination, prediction error, calibration-oriented checks, and nonparametric cumulative incidence with competing risks.

## Installation
Create an isolated environment using `uv`:
```bash
uv venv .venv-survival --python 3.13
source .venv-survival/bin/activate
uv pip install \
  "scikit-survival==0.28.0" \
  "scikit-learn==1.9.1" \
  "numpy==2.5.1" \
  "pandas==3.0.6" \
  "scipy==1.18.1" \
  "ecos==2.0.14" \
  "osqp==1.1.3" \
  "joblib==1.6.0" \
  "numexpr==2.14.2" \
  "narwhals==2.26.0"
```

## Non-negotiable Workflow
1. **Define the estimand and event coding.** Decide whether the target is all-event survival, cause-specific hazard, or cause-specific cumulative incidence.
2. **Validate outcomes.** Standard estimators need a two-field structured array: boolean event first, observed time second. Competing-risk CIF needs a separate integer event vector: 0=censored, 1..K=causes.
3. **Split before learned preprocessing.** Never fit imputers, encoders, scalers, or feature selectors on all rows before splitting.
4. **Fit preprocessing inside a pipeline.** Unknown categories and missingness must be handled using training-fold state only.
5. **Tune without reusing evaluation data.** Use nested CV when reporting cross-validated tuned performance, or reserve a truly untouched final holdout.
6. **Fit censoring distributions on training data.** IPCW concordance, dynamic AUC, and Brier metrics receive `survival_train`, never a pooled train+test outcome.
7. **Restrict evaluation times.** Use a strictly increasing grid inside test follow-up and below the end of training support where the estimated censoring survival remains positive.
8. **Match predictions to metrics.** Concordance/dynamic AUC consume higher-is-riskier scores. Brier metrics consume survival probabilities with shape `(n_test, n_times)`.
9. **Handle competing causes explicitly.** Never estimate event-specific probability with `1 - Kaplan-Meier` while censoring competing events.
10. **Report limits.** Separate discrimination, calibration, prediction error, and cumulative incidence.

## Model Selection Heuristics
- **High-dimensional (p > n)**: Prefer `CoxnetSurvivalAnalysis` (Elastic Net) for stability and feature selection.
- **Interpretability required**: Prefer `CoxPHSurvivalAnalysis` (coefficients as log hazard ratios).
- **Strong non-linearities / interactions**: Prefer `RandomSurvivalForest` or `GradientBoostingSurvivalAnalysis`.
- **Kernelized decision boundaries**: Consider `FastKernelSurvivalSVM` (ensure scaling).

## Outcome Construction
```python
from sksurv.util import Surv

y = Surv.from_arrays(event=event_bool, time=observed_time)
# Equivalent for pandas or Polars:
y = Surv.from_dataframe("event", "time", frame)
```

## Leakage-safe Pipeline Example
```python
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sksurv.linear_model import CoxPHSurvivalAnalysis

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, stratify=y["event"], random_state=20260723
)

preprocess = ColumnTransformer(
    [
        ("num", make_pipeline(SimpleImputer(strategy="median"), StandardScaler()), numeric),
        (
            "cat",
            make_pipeline(
                SimpleImputer(strategy="most_frequent"),
                OneHotEncoder(handle_unknown="ignore", drop="first", sparse_output=False),
            ),
            categorical,
        ),
    ],
    sparse_threshold=0.0,
)
model = make_pipeline(preprocess, CoxPHSurvivalAnalysis())
```

## Evaluation
Use censoring-aware metrics. For IPCW-based metrics like Uno's C-index, always pass `y_train` to estimate the censoring distribution.

```python
from sksurv.metrics import concordance_index_ipcw, integrated_brier_score

# Uno's C-index (IPCW)
c_uno = concordance_index_ipcw(y_train, y_test, risk_scores)[0]

# Integrated Brier Score
ibs = integrated_brier_score(y_train, y_test, survival_functions, times)
```