在 Python 中为 Kaplan-Meier 图模拟生存数据
像 lifelines 这样的库提供了大量可以使用的示例数据集。但是,对于许多任务,你需要模拟生存曲线中的特定行为。
在此文章中,我们演示一个简单的算法,以类似于 lifelines 示例数据集(如 load_leukemia())中使用的格式生成生存数据。
生成算法基于以下假设:
- 存在严格的生存平台期,从给定时间点开始具有给定的生存概率
- 从 100% 生存、t=0 到生存平台期的进展是近似线性的(即如果你生成无限数量的数据点,生存曲线将是线性的)
- 不生成删失事件,除了在时间线终点对所有存活参与者进行删失。
代码:
simulate_survival_linear.py
import numpy as np
import random
from lifelines import KaplanMeierFitter
def simulate_survival_data_linear(N, survival_plateau, t_plateau, t_end):
"""
使用线性模型生成随机模拟生存数据
关键字参数
------------------
N : 整数
要生成的条目数
survival_plateau : 浮点数
生存平台期的生存概率
t_plateau : 浮点数
生存平台期开始的时间点
t_end : 浮点数
所有存活参与者将被删失的时间点。
返回
-------
包含 "Time" 和 "Event" numpy 数组的字典:0 为删失,1 为事件
"""
data = {"Time": np.zeros(N), "Event": np.zeros(N)}
for i in range(N):
r = random.random()
if r <= survival_plateau:
# 事件是时间段结束时的删失
data["Time"][i] = t_end
data["Event"][i] = 0
else: # 事件发生
# 归一化我们在 100% 和生存平台期之间的位置
p = (r - survival_plateau) / (1 - survival_plateau)
# 线性模型:事件时间线性依赖于均匀随机选择的位置
# 在范围 (0...tplateau) 内
t = p * t_plateau
data["Time"][i] = t
data["Event"][i] = 1
return data
# 示例用法
data1 = simulate_survival_data_linear(250, 0.2, 18, 24)
data2 = simulate_survival_data_linear(250, 0.4, 17.2, 24)给定 data1 和 data2(参见代码末尾的用法示例),你可以使用以下命令绘制它们
plot_kaplan_meier.py
# 绘制不良亚组
kmf1 = KaplanMeierFitter()
kmf1.fit(data1["Time"], event_observed=data1["Event"], label="Bad subgroup")
ax = kmf1.plot()
# 绘制良好亚组
kmf2 = KaplanMeierFitter()
kmf2.fit(data2["Time"], event_observed=data2["Event"], label="Good subgroup")
ax = kmf2.plot(ax=ax)
# 将 Y 轴设置为固定比例
ax.set_ylim([0.0, 1.0])不想要生存平台期?
只需设置 t_end = t_survival:
simulate_survival_no_plateau.py
# 示例用法
data1 = simulate_survival_data_linear(250, 0.2, 24, 24)
data2 = simulate_survival_data_linear(250, 0.4, 24, 24)
# 绘图代码:见上文如果参与者数量少会怎样?
让我们使用 25 而不是上面的 250:
simulate_survival_low_n.py
# 示例用法
data1 = simulate_survival_data_linear(25, 0.2, 24, 24)
data2 = simulate_survival_data_linear(25, 0.4, 24, 24)
# 绘图代码:见上文虽然我们用相同的数据生成了数据,但在此示例中差异不那么明显,特别是在时间线末端附近(但注意数据是随机生成的,所以你可能看到不同的结果)。你可以看到大部分置信区间在 t=24 附近重叠。换句话说,基于此数据不清楚两组患者是否有显著差异(换句话说,$P \geq 0.05$)
Check out similar posts by category:
Python, Statistics
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow