可视化你的 Kaplan–Meier 模型

Python 中的生存分析

Shae Wang

Senior Data Scientist

如何构建 Kaplan–Meier 生存曲线?

示例数据,$n=5$:

duration observed
2 1
5 0
3 1
5 1
2 0

步骤 1: 按升序排列数据。若相同时间,删失数据排在未删失之后。

步骤 2: 对每个 $t_i$,计算 $d_i$、$n_i$ 和 $\big(1-\frac{d_i}{n_i}\big)$

步骤 3: 对每个 $t_i$,将 $\big(1-\frac{d_i}{n_i}\big)$ 依次与 $\big(1-\frac{d_{i-1}}{n_{i-1}}\big)$、$\big(1-\frac{d_{i-2}}{n_{i-2}}\big)$ … $\big(1-\frac{d_0}{n_0}\big)$ 相乘

Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 1: 将时间按升序排列。若相同时间,删失数据排在未删失之后。

duration
2
5+
3
5
2+

使用"+"表示删失:2, 5+, 3, 5, 2+

Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 1: 将时间按升序排列。若相同时间,删失数据排在未删失之后。

$t_i$
2, 2+
3
5, 5+
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 2: 对每个 $t_i$,计算 $d_i$、$n_i$ 和 $\big(1-\frac{d_i}{n_i}\big)$

$t_i$
2, 2+
3
5, 5+
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 2: 对每个 $t_i$,计算 $d_i$、$n_i$ 和 $\big(1-\frac{d_i}{n_i}\big)$

$t_i$ $d_i$
2, 2+ 1
3 1
5, 5+ 1
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 2: 对每个 $t_i$,计算 $d_i$、$n_i$ 和 $\big(1-\frac{d_i}{n_i}\big)$

$t_i$ $d_i$ $n_i$
2, 2+ 1 5
3 1 3
5, 5+ 1 2
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 2: 对每个 $t_i$,计算 $d_i$、$n_i$ 和 $\big(1-\frac{d_i}{n_i}\big)$

$t_i$ $d_i$ $n_i$ $\big(1-\frac{d_i}{n_i}\big)$
2, 2+ 1 5 $4/5$
3 1 3 $2/3$
5, 5+ 1 2 $1/2$
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

步骤 3: 对每个 $t_i$,将 $\big(1-\frac{d_i}{n_i}\big)$ 依次与 $\big(1-\frac{d_{i-1}}{n_{i-1}}\big)$、$\big(1-\frac{d_{i-2}}{n_{i-2}}\big)$ … $\big(1-\frac{d_0}{n_0}\big)$ 相乘

$t_i$ $d_i$ $n_i$ $\big(1-\frac{d_i}{n_i}\big)$ $S(t_i)$
2, 2+ 1 5 4/5 4/5 = 0.8
3 1 3 2/3 4/5 $\cdot$ 2/3 = 0.53
5, 5+ 1 2 1/2 4/5 $\cdot$ 2/3 $\cdot$ 1/2 = 0.27
Python 中的生存分析

如何构建 Kaplan–Meier 生存曲线?

$t_i$ $d_i$ $n_i$ $\big(1-\frac{d_i}{n_i}\big)$ $S(t_i)$
2, 2+ 1 5 $4/5$ 0.8
3 1 3 $2/3$ 0.53
5, 5+ 1 2 $1/2$ 0.27

来自表格的 Kaplan–Meier 曲线。

Python 中的生存分析

解读生存曲线

来自表格的 Kaplan–Meier 曲线。

  • 0 到 5 之间各时间点的生存概率。

  • 常见误解:曲线到 0 表示无人存活。

  • 若最后一次观测未删失(真实事件时间已知),曲线会降至 0。
Python 中的生存分析

绘制 Kaplan–Meier 生存曲线

from lifelines import KaplanMeierFitter
import matplotlib.pyplot as plt

kmf = KaplanMeierFitter()
kmf.fit(durations, event_observed)
kmf.survival_function_.plot()
plt.show()
Python 中的生存分析

房贷问题示例

DataFrame 名称:mortgage_df

id duration paid_off
1 25 0
2 17 1
3 5 0
... ... ...
100 30 1
from lifelines import KaplanMeierFitter
from matplotlib import pyplot as plt
mortgage_kmf = KaplanMeierFitter()
mortgage_kmf.fit(duration=mortgage_df["duration"], 
        event_observed=mortgage_df["paid_off"])
mortgage_kmf.survival_function_.plot()
Python 中的生存分析

房贷问题示例

plt.show()

房贷问题的生存曲线可视化。

Python 中的生存分析

生存曲线的置信区间

mortgage_kmf.plot_survival_function()
plt.show()

带置信区间的房贷生存曲线可视化。

Python 中的生存分析

置信区间有何用?

  • 量化每个生存概率点估计的不确定性
  • 置信区间越宽,越不确定,常因样本量小
  • 置信区间越窄,越确定,常因样本量大
Python 中的生存分析

绘制 Kaplan–Meier 生存曲线的多种方式

将生存函数点估计绘制为连续曲线。

kmf.survival_function_.plot()
plt.show()

连续曲线形式的生存函数图。

将生存函数绘制为阶梯线,不含置信区间。

kmf.plot(ci_show=False)
plt.show()

阶梯线形式的生存函数图。

Python 中的生存分析

绘制 Kaplan–Meier 生存曲线的多种方式

将生存函数绘制为带置信区间的阶梯线。

kmf.plot()
plt.show()

带置信区间的阶梯线生存函数图。

另一种方式…

kmf.plot_survival_function()
plt.show()
Python 中的生存分析

Passons à la pratique !

Python 中的生存分析

Preparing Video For Download...