跳到正文

临床研究生存分析

使用 scikit-survival 组织含删失资料的生存分析,明确研究终点、模型评价和结果解释范围。

开源精选医疗业务16 个文件50,135 Stars浏览次数 0K-Dense-AI/scientific-agent-skills MIT版本 a1043ef
开始使用

适用环境:Requires Python 3.11+, uv, and the pinned scikit-survival 0.28.0 stack for executable examples. Bundled CLIs are local and network-free by default.

输入资料
获准使用的研究数据与终点定义 生存时间、事件信息及分析环境 阅读本节完整说明
交付内容
可复查的生存分析流程 模型评价与研究限制说明 阅读本节完整说明
环境与依赖
Verified 2026-10-01: Latest stable: scikit-survival 0.28.0, released 2026-07-05. Python: 3.11 or later; PyPI wheels cover CPython 3.11-3.14 on Linux x86-64, macOS x86-64/ARM64, and Windows x86-64. Runtime bounds: NumPy >… 阅读本节完整说明
  1. 获取完整包,保留配套文件的目录结构。
  2. 按照原文准备所需工具、依赖与输入资料。
  3. 阅读对应使用步骤与输入输出说明,在自己的环境中验证结果。

使用提示摘自原文,配套文件保留来源版本;实际运行条件以各包说明为准。

正文

获取原文件

references/svm-models.md

Verified for scikit-survival 0.28.0 on 2026-10-01.

What survival SVMs predict

Survival SVMs optimize ranking, regression, or a mixture. They generally return a scalar score, not a baseline survival function or cumulative hazard function. Therefore:

  • use concordance or cumulative/dynamic AUC only after confirming score direction;
  • do not pass SVM output to Brier metrics;
  • do not convert a margin to event probability without a separately validated calibration model and protocol.

Fast linear survival SVM

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sksurv.svm import FastSurvivalSVM

model = make_pipeline(
    StandardScaler(),
    FastSurvivalSVM(
        alpha=1.0,
        rank_ratio=1.0,
        max_iter=1000,
        tol=1e-5,
        random_state=20260723,
    ),
)
model.fit(X_train, y_train)
risk = model.predict(X_test)

Current signature:

FastSurvivalSVM(
    alpha=1, *,
    rank_ratio=1.0,
    fit_intercept=False,
    max_iter=20,
    verbose=False,
    tol=None,
    optimizer=None,
    random_state=None,
    timeit=False,
)

Key semantics:

  • rank_ratio=1.0: ranking-only objective; higher predictions indicate shorter survival/higher event risk.
  • 0 < rank_ratio < 1: mixed ranking and regression.
  • rank_ratio=0.0: regression-only objective.
  • When rank_ratio < 1, predict() exponentiates the log-time predictor and returns original-time values: lower prediction means shorter survival. For a metric requiring higher event risk, use -prediction and document the conversion.
  • alpha weights the data-fit/ranking objective relative to the penalty, so larger values mean less regularization; tune it within inner CV.

Do not use an arbitrary sign simply because a C-index improves. The sign follows the model objective and target interpretation.

Fast kernel survival SVM

from sksurv.svm import FastKernelSurvivalSVM

model = FastKernelSurvivalSVM(
    alpha=1.0,
    rank_ratio=1.0,
    kernel="rbf",
    gamma=0.05,
    max_iter=100,
    tol=1e-5,
    random_state=20260723,
)
model.fit(X_train_scaled, y_train)
risk = model.predict(X_test_scaled)

Current signature:

FastKernelSurvivalSVM(
    alpha=1, *,
    rank_ratio=1.0,
    fit_intercept=False,
    kernel="rbf",
    gamma=None,
    degree=3,
    coef0=1,
    kernel_params=None,
    max_iter=20,
    verbose=False,
    tol=None,
    optimizer=None,
    random_state=None,
    timeit=False,
)

Kernel choices follow scikit-learn pairwise-kernel behavior, including "linear", "poly", "rbf", "sigmoid", callable kernels, and "precomputed" where supported. Do not copy older examples that use gamma="scale" without checking the current API; the current scikit-survival parameter default is None.

Kernel fitting and prediction depend on training rows and can require quadratic-size kernel matrices. Enforce row/memory bounds before fitting.

Hinge, Minlip, and naive formulations

Current additional estimators:

  • HingeLossSurvivalSVM(alpha=1.0, solver="ecos", kernel="linear", pairs="all", ...)
  • MinlipSurvivalAnalysis(alpha=1.0, solver="ecos", kernel="linear", pairs="nearest", ...)
  • NaiveSurvivalSVM(penalty="l2", loss="squared_hinge", dual=False, alpha=1.0, ...)

Important current differences:

  • HingeLossSurvivalSVM and MinlipSurvivalAnalysis do not have a random_state constructor parameter.
  • Their convex optimization defaults to the ECOS solver.
  • Pair construction and kernel matrices can become expensive.
  • NaiveSurvivalSVM uses a linear-SVM-style formulation and is mainly useful for small comparisons; it is not the fast implementation.

Use the exact current signature rather than transferring parameters across SVM classes.

Scaling and explicit preprocessing

Scale continuous features and fit scaling only on training folds:

from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

preprocess = ColumnTransformer(
    [
        (
            "num",
            make_pipeline(SimpleImputer(strategy="median"), StandardScaler()),
            numeric_columns,
        ),
        (
            "cat",
            make_pipeline(
                SimpleImputer(strategy="most_frequent"),
                OneHotEncoder(
                    drop="first",
                    handle_unknown="ignore",
                    sparse_output=False,
                ),
            ),
            categorical_columns,
        ),
    ],
    sparse_threshold=0.0,
)
model = make_pipeline(
    preprocess,
    FastSurvivalSVM(rank_ratio=1.0, random_state=20260723),
)

Do not call StandardScaler.fit_transform(X) before cross-validation. Keeping it inside the pipeline makes every inner and outer fold independent.

Kernel preprocessing

For "precomputed", training input must be a square (n_train, n_train) kernel matrix; test input must be (n_test, n_train) with columns in the identical training order.

sksurv.kernels.ClinicalKernelTransform and clinical_kernel() support mixed continuous, ordinal, and nominal DataFrame columns, including pandas/Polars in 0.28. They do not accept an ad hoc list of (clinical, molecular) tuples as a special API. Fit the transform on a clearly typed training DataFrame or explicitly precompute the kernel:

from sksurv.kernels import ClinicalKernelTransform
from sksurv.svm import FastKernelSurvivalSVM

kernel = ClinicalKernelTransform()
kernel_train = kernel.fit_transform(X_train_typed)
kernel_test = kernel.transform(X_test_typed)

model = FastKernelSurvivalSVM(
    kernel="precomputed",
    rank_ratio=1.0,
    random_state=20260723,
)
model.fit(kernel_train, y_train)
risk = model.predict(kernel_test)

The one-shot clinical_kernel(X_test, X_train) infers numeric ranges from both arguments, changing normalization with the test cohort. Prefer the fitted transform above. The released one-shot Cython routine also allocates its range buffer by row count while writing one value per numeric feature: avoid that routine when numeric features outnumber rows (source finding; unsafe case not executed). Put ClinicalKernelTransform() inside the pipeline for CV so its ranges and reference rows are learned afresh in every fold. Out-of-training-range values can produce negative similarities in the native transform; inspect support and define any clipping/extrapolation policy before evaluating.

Any data-dependent kernel typing, scaling, or parameter choice belongs inside the training/CV protocol.

Nested tuning

Tune at least alpha; for kernel models also tune kernel and its parameters. Keep the grid bounded:

from sklearn.model_selection import GridSearchCV

search = GridSearchCV(
    pipeline,
    {
        "fastkernelsurvivalsvm__alpha": [0.1, 1.0, 10.0],
        "fastkernelsurvivalsvm__gamma": [0.01, 0.05, 0.2],
    },
    cv=inner_splits,
    error_score="raise",
    n_jobs=1,
)
search.fit(X_outer_train, y_outer_train)

The actual parameter prefix depends on pipeline step names. Run this search within each outer fold for a nested-CV performance estimate. Do not:

  • fit a scaler or kernel transform before the outer split;
  • select the sign, kernel, or horizon on outer-validation results;
  • reuse the final test set to choose alpha/gamma;
  • compare SVM Brier scores, because SVMs do not output survival probabilities.

For IPCW metrics, fit the censoring distribution on the corresponding outer training outcomes and keep the time grid within that fold's support.

Choosing an SVM candidate

  • Linear ranking objective: a scalable margin-based discrimination baseline.
  • Kernel ranking objective: nonlinear relationships when row count permits.
  • Mixed/regression objective: time-oriented score, with different sign semantics.
  • Need absolute survival probability: choose a model with predict_survival_function() or add a separately validated calibration stage.
  • Need coefficient/hazard-ratio interpretation: use an appropriate Cox model, not an SVM margin.

These are capability distinctions, not guarantees of performance.

Interpretation

SVM margins are arbitrary-scale predictions. A high C-index or dynamic AUC says that orderings discriminate under the chosen censoring estimator and horizon; it does not establish:

  • probability calibration;
  • causal or treatment effects;
  • transportability;
  • subgroup fairness;
  • clinical or decision utility.

Report optimization convergence, score direction, kernel, preprocessing, tuning resamples, and censoring assumptions.

Sources

Official sources checked 2026-10-01:

CONTACT HAONAN

联系haonan

医疗 AI · 产品与独立开发

刘浩南

关注医疗 AI 从 demo 到真实落地,聚焦产品化、商业化与院内工作流效率提升。

12年医疗产研经验,大湾区头部医疗AI公司前产品总监,独立开发者

医疗 AI 产品化医疗 AI 商业化院内工作流效率
刘浩南的微信联系二维码
微信扫一扫,联系 haonan