4、生存分析基础:生存函数、风险函数、删失数据、Kaplan-Meier曲线
在临床试验、队列研究和可靠性工程中,我们经常关注“某个事件发生的时间”,例如患者死亡、疾病复发、设备失效或用户流失。这类数据与普通连续变量(如血压、体重)有本质区别:部分观察对象在研究结束时仍未发生事件,或中途失访,我们只知道其“未发生事件的时间下限”,却不知道确切的事件时间。生存分析(Survival Analysis)正是处理这类“时间-事件”数据的统计框架。本章将系统讲解生存分析的四大基石:生存函数、风险函数、删失数据以及最常用的非参数估计方法——Kaplan-Meier曲线,帮助您建立对生存数据的完整认知框架。
上图展示了生存分析中四个核心概念的内在逻辑关系:生存数据(时间-事件数据)是分析的起点,生存函数和风险函数是从不同角度刻画事件时间分布的两个互补工具,删失数据则是生存数据区别于普通连续数据的根本特征,而Kaplan-Meier估计则是将上述概念落地为实际统计推断的经典非参数方法。下面我们逐一深入展开。
4.1 生存函数:从“存活概率”到时间分布
4.1.1 核心原理
生存函数(Survival Function),记作 S(t),定义为个体从起始时间到某个特定时刻 t 之后仍未发生事件的概率:
S(t) = P(T > t) = 1 - F(t)
其中 T 是事件发生时间(随机变量),F(t) 是累积分布函数。生存函数具有三个基本性质:
- 单调非增:随着时间推移,生存概率只会下降或保持不变,不会上升。
- 边界条件:S(0) = 1(起始时刻所有人都未发生事件),S(∞) = 0(理论上最终所有个体都会发生事件)。
- 与密度函数的关系:f(t) = -dS(t)/dt,即事件密度函数是生存函数的负导数。
生存函数直观地回答了“到某个时间点,还有多大比例的人/设备/用户没有发生事件”这一问题。在临床研究中,5年生存率就是 S(5) 的估计值;在可靠性工程中,可靠度函数 R(t) 与生存函数完全同构。
4.1.2 判断方法与操作流程
在实际数据分析中,我们通常通过以下步骤构建生存函数:
- 定义时间起点和事件:明确“时间0”是什么(如入组日期、手术日期、产品上线日期),事件是什么(死亡、复发、故障、流失)。
- 整理数据格式:每条记录至少包含三个字段——个体ID、观察时间(事件时间或删失时间)、事件指示符(1=发生事件,0=删失)。
- 选择估计方法:非参数方法(KM估计)适用于无分布假设的场景;参数方法(如指数分布、Weibull分布)适用于已知分布形态的场景;半参数方法(Cox回归)用于多因素分析。
- 计算并绘图:使用统计软件(R的survival包、Python的lifelines库、SAS的PROC LIFETEST)计算生存概率并绘制阶梯形曲线。
4.1.3 案例拆解:新药延长生存期的初步判断
假设某肿瘤临床试验入组100例晚期患者,随机分为试验组(新药+化疗)和对照组(安慰剂+化疗),各50例。随访36个月,记录死亡时间或删失时间。初步分析时,我们计算试验组的KM生存曲线:在12个月时,S(12) = 0.78,即试验组78%的患者在12个月时仍然存活;对照组S(12) = 0.61。两组曲线在早期(0-6个月)几乎重叠,但在12个月后明显分离,试验组曲线始终在对照组上方。这个初步信号提示新药可能延长了生存期,但还需要通过Log-rank检验(见后续章节)确认差异是否具有统计学显著性,并计算中位生存时间(试验组22个月 vs 对照组15个月)作为临床获益的量化指标。
4.2 风险函数:捕捉“瞬时风险”的动态变化
4.2.1 核心原理
风险函数(Hazard Function),记作 h(t),定义为在时刻 t 仍然存活(未发生事件)的条件下,在极短时间间隔 [t, t+Δt) 内发生事件的瞬时速率:
h(t) = lim_{Δt→0} P(t ≤ T < t+Δt | T ≥ t) / Δt
风险函数与生存函数存在严格的数学关系:h(t) = f(t) / S(t),且 S(t) = exp(-∫₀ᵗ h(u)du)。累积风险函数 H(t) = ∫₀ᵗ h(u)du = -ln S(t)。
风险函数的核心价值在于它刻画了“条件风险”的时间动态:
- 递增风险:如老年人群的死亡风险随年龄增长而上升。
- 递减风险:如手术后感染风险随时间推移而下降。
- 浴盆曲线:早期风险高(婴儿死亡率或设备早期失效),中期平稳,后期再次上升(老化)。
- 恒定风险:指数分布对应的风险函数为常数,表示事件发生无“记忆性”。
4.2.2 判断方法与操作流程
风险函数的估计通常比生存函数更复杂,常用方法包括:
- 核平滑估计:对事件时间做核密度估计后除以生存函数估计值。
- 分段常数模型:将时间轴划分为若干区间,假设每个区间内风险恒定。
- 参数模型:假设风险函数服从特定形式(如Weibull风险 h(t) = λγt^(γ-1)),通过极大似然估计参数。
- 残差诊断:通过Cox-Snell残差检验模型拟合优度。
4.2.3 实战场景:心脏移植术后风险窗口
某心脏移植中心分析200例移植患者的术后生存数据,发现风险函数呈现明显的“双峰”特征:术后30天内风险最高(h(t) ≈ 0.08/天),随后快速下降至第90天的最低点(h(t) ≈ 0.01/天),之后缓慢上升。这一发现提示:早期风险主要来自手术并发症和急性排斥反应,中期风险较低,而远期风险上升可能与慢性排斥和移植物血管病变有关。基于此,临床团队将术后第一个月作为“强化监护窗口”,第3-12个月作为“免疫抑制调整期”,1年后转为“慢性病管理”。这种风险函数分析直接指导了临床随访策略的制定。
4.3 删失数据:生存分析必须面对的“不完整信息”
4.3.1 核心原理
删失(Censoring)是指我们无法观察到个体发生事件的准确时间,只知道事件发生在某个时间点之前、之后或某个区间内。删失是生存数据区别于普通连续数据的根本特征,也是生存分析专门发展出一套统计方法的原因。根据删失发生的位置,可分为三类:
| 删失类型 | 定义 | 典型场景 | 对分析的影响 |
|---|---|---|---|
| 右删失(Right) | 事件发生在观察截止时间之后,只知道 T > C | 研究结束时患者仍存活;患者中途失访 | 最常见,KM估计和Cox模型均能处理 |
| 左删失(Left) | 事件发生在观察开始之前,只知道 T < C | 入组时已感染但不知感染时间 | 较少见,需特殊方法(如Turnbull估计) |
| 区间删失(Interval) | 事件发生在两次随访之间,只知道 L ≤ T ≤ R | 定期随访检查发现肿瘤复发 | 需区间删失专用方法 |
删失数据的关键假设是非信息性删失(Non-informative Censoring):删失机制与事件发生时间相互独立。例如,患者因病情恶化而退出试验(信息性删失)会严重偏倚结果,而因搬家失访(非信息性删失)则相对安全。
4.3.2 判断方法与操作流程
处理删失数据时,必须遵循以下原则:
- 明确删失类型:在数据收集阶段就定义清楚删失的判定标准,避免事后猜测。
- 正确编码:通常用 status=1 表示事件发生,status=0 表示删失;时间变量记录 min(T, C)。
- 检查删失比例:若删失比例超过40%,需警惕结果稳健性,可进行敏感性分析(如假设删失为事件或非事件,观察结论是否改变)。
- 验证非信息性删失假设:比较删失组与非删失组的基线特征,若差异显著,需考虑使用加权方法或联合建模。
4.3.3 案例拆解:失访患者的“贡献”如何计算
一项高血压药物长期疗效研究入组500例患者,计划随访5年。实际结束时,320例发生心血管事件,180例删失(其中120例完成5年随访未发生事件,60例中途失访)。在KM估计中,这180例删失患者并非被简单剔除:他们在删失前的时间段内为风险集(risk set)贡献了“人-时间”,从而影响每个事件时间点的分母 n_i。例如,在第2年有10例事件发生时,风险集人数 n_i 包含了所有在2年时仍存活且未删失的患者(包括后来在第3年失访的患者)。这种“直到删失时刻为止都有效”的处理方式,充分利用了删失数据中的部分信息,是生存分析高效利用数据的关键。
4.4 Kaplan-Meier曲线:非参数生存估计的黄金标准
4.4.1 核心原理
Kaplan-Meier估计(又称乘积极限法,Product-Limit Method)是估计生存函数最常用的非参数方法,由Kaplan和Meier于1958年提出。其核心思想是:将生存概率分解为一系列条件概率的乘积。假设有 k 个不同的事件发生时间 t₁ < t₂ < ... < tₖ,在时间 tᵢ 有 dᵢ 个事件发生,风险集人数为 nᵢ(即在 tᵢ 之前未发生事件且未删失的人数),则KM估计为:
Ŝ(t) = Π_{tᵢ ≤ t} (1 - dᵢ / nᵢ)
KM估计具有以下优良性质:
- 无分布假设:不要求数据服从特定分布,适用于各种生存数据。
- 充分利用删失信息:删失个体在删失前始终贡献于风险集。
- 阶梯形曲线:仅在事件发生时间点下降,删失时间点用短竖线(+)标记。
- 大样本一致性:样本量足够大时,KM估计收敛于真实生存函数。
4.4.2 操作流程与软件实现
使用Python的lifelines库绘制KM曲线的标准流程如下:
from lifelines import KaplanMeierFitter
import pandas as pd
# 数据准备:duration为观察时间,event为事件指示符(1=事件,0=删失)
df = pd.DataFrame({
'duration': [6, 12, 18, 24, 30, 36, 6, 12, 18, 24],
'event': [1, 1, 0, 1, 0, 1, 1, 0, 1, 0]
})
# 拟合KM模型
kmf = KaplanMeierFitter()
kmf.fit(durations=df['duration'], event_observed=df['event'])
# 输出生存概率表
kmf.event_table
# 绘制曲线
kmf.plot_survival_function()
关键输出包括:每个事件时间点的风险集人数 nᵢ、事件数 dᵢ、生存概率 Ŝ(t) 及其95%置信区间。中位生存时间定义为 Ŝ(t) 首次小于0.5的时间点。
4.4.3 案例拆解:两组生存曲线的完整比较
某医疗器械公司比较两种人工关节(A型陶瓷 vs B型金属)的10年生存率(以翻修手术为事件)。入组各120例,随访10年。A组:10年时30例翻修,90例删失(其中75例完成10年随访未翻修,15例失访);B组:10年时55例翻修,65例删失。KM分析结果:
| 时间点 | A组生存率 (95%CI) | B组生存率 (95%CI) |
|---|---|---|
| 1年 | 98.3% (95.9-100%) | 97.5% (94.7-100%) |
| 3年 | 93.2% (89.0-97.6%) | 88.4% (83.1-94.0%) |
| 5年 | 87.5% (81.8-93.6%) | 76.3% (69.0-84.4%) |
| 10年 | 75.0% (67.2-83.7%) | 54.2% (45.3-64.8%) |
中位生存时间:A组未达到(10年时生存率仍>50%),B组为8.2年。Log-rank检验 p=0.003,差异有统计学意义。进一步分析发现,A组在5年后的曲线下降速度明显放缓,而B组持续下降,提示陶瓷关节的远期耐磨性更优。但需注意:A组15例失访中,有8例发生在第8年后,若这些患者实际已翻修(信息性删失),则A组生存率可能被高估。因此进行了敏感性分析:将失访者全部视为翻修,A组10年生存率降至68.5%,差异仍显著(p=0.018),结论稳健。
4.5 总结复盘:生存分析基础概念的应用要点
本章四个核心概念构成了生存分析的完整逻辑链:生存函数回答“到某时刻还有多少比例未发生事件”,风险函数回答“在某时刻存活的条件下,瞬时发生事件的速度有多快”,删失数据提醒我们数据中天然存在信息不完整性,而KM曲线则是将前三个概念整合为可操作的统计工具。在实际应用中,建议遵循以下流程:
- 数据清洗:确认时间变量和事件指示符的编码正确,检查是否存在时间≤0或事件指示符缺失的记录。
- 描述性分析:计算删失比例,绘制KM曲线,观察曲线形态(是否交叉、下降速度变化)。
- 组间比较:使用Log-rank检验(或Breslow检验,当早期差异更重要时)比较两组或多组生存曲线。
- 多因素调整:当存在混杂因素时,使用Cox比例风险模型(后续章节详述)。
- 敏感性分析:对删失机制做不同假设,验证结论的稳健性。
生存分析不是简单的“画一条下降曲线”,而是对“时间-事件”数据背后生物学、工程学或社会学机制的深入探索。掌握本章基础概念后,您将能够正确解读临床文献中的生存曲线,并为后续学习Cox回归、参数生存模型和竞争风险模型打下坚实基础。