scipy.stats.

logrank#

scipy.stats.logrank(x, y, alternative='two-sided')[source]#

通过 logrank 检验比较两个样本的生存分布。

参数:
x, y类数组或 CensoredData

基于其生存函数比较的样本。

alternative{‘two-sided’, ‘less’, ‘greater’}, 可选

定义备择假设。

零假设是两个组的生存分布(假设为 XY)相同。

以下备择假设 [4] 可用(默认值是 ‘two-sided’)

  • ‘two-sided’:两个组的生存分布不相同。

  • ‘less’:X 组的生存率较优:X 组失效率函数在某些时间点小于 Y 组失效率函数。

  • ‘greater’:Y 组的生存率较优:X 组失效率函数在某些时间点大于 Y 组失效率函数。

返回:
resLogRankResult

一个包含属性的对象

statistic浮点ndarray

计算出的统计信息(定义见下文)。它的幅度是大多数其他 logrank 测试实现返回的幅度的平方根。

pvalue浮点ndarray

测试计算的p值。

注意

logrank 测试 [1] 比较了观测事件数与空假设(两个样本取自同一分布)下的事件预期数。该统计量为

\[Z_i = \frac{\sum_{j=1}^J(O_{i,j}-E_{i,j})}{\sqrt{\sum_{j=1}^J V_{i,j}}} \rightarrow \mathcal{N}(0,1)\]

其中

\[E_{i,j} = O_j \frac{N_{i,j}}{N_j}, \qquad V_{i,j} = E_{i,j} \left(\frac{N_j-O_j}{N_j}\right) \left(\frac{N_j-N_{i,j}}{N_j-1}\right),\]

\(i\) 表示组(即可能取值\(x\)\(y\),或者可以省略以引用合并后的样本)\(j\) 表示时间(发生事件时),\(N\) 是事件发生前有风险的受试者数量,而\(O\) 是此时观察到的事件数量。

logrank 返回的 statistic \(Z_x\) 是许多其他实现返回的统计量的(带符号)平方根。在空假设下,\(Z_x**2\) 在渐近分布上根据自由度为 1 的卡方分布分布。因此,\(Z_x\) 在渐近分布上根据标准正态分布分布。使用 \(Z_x\) 的优点在于它保留了符号信息(即观测到的事件数量是否趋向于小于或大于空假设下的预期数量),允许 scipy.stats.logrank 提供单边替代假设。

参考

[1]

Mantel N.“对生存数据和针对其考虑中出现的两个新等级统计量的评估。”Cancer Chemotherapy Reports, 50(3):163-170, PMID: 5910392, 1966

[2]

Bland, Altman,"logrank 测试”, BMJ, 328:1073, DOI:10.1136/bmj.328.7447.1073, 2004

[3]

“Logrank 测试”,Wikipedia, https://en.wikipedia.org/wiki/Logrank_test

[4]

Brown, Mark。“关于 log 等级测试方差的选择。”Biometrika 71.1 (1984): 65-74。

[5]

Klein, John P., 和 Melvin L. Moeschberger。生存分析:用于审查和截断数据的技术。卷 1230。纽约:施普林格,2003 年。

范例

参考文献 [2] 比较了两种不同类型复发性恶性神经胶质瘤患者的生存时间。下表记录了每个患者参加研究的时间(以周为单位)。scipy.stats.CensoredData 类用于数据右删失的情况:非删失观察对应于观察到的死亡,而删失观察对应于患者出于其他原因退出研究。

>>> from scipy import stats
>>> x = stats.CensoredData(
...     uncensored=[6, 13, 21, 30, 37, 38, 49, 50,
...                 63, 79, 86, 98, 202, 219],
...     right=[31, 47, 80, 82, 82, 149]
... )
>>> y = stats.CensoredData(
...     uncensored=[10, 10, 12, 13, 14, 15, 16, 17, 18, 20, 24, 24,
...                 25, 28,30, 33, 35, 37, 40, 40, 46, 48, 76, 81,
...                 82, 91, 112, 181],
...     right=[34, 40, 70]
... )

我们可以按如下方式计算和可视化两个组的经验生存函数。

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> ax = plt.subplot()
>>> ecdf_x = stats.ecdf(x)
>>> ecdf_x.sf.plot(ax, label='Astrocytoma')
>>> ecdf_y = stats.ecdf(y)
>>> ecdf_y.sf.plot(ax, label='Glioblastoma')
>>> ax.set_xlabel('Time to death (weeks)')
>>> ax.set_ylabel('Empirical SF')
>>> plt.legend()
>>> plt.show()
../../_images/scipy-stats-logrank-1_00_00.png

目测经验生存函数表明两组的生存时间往往不同。要正式评估差异在 1% 显著性水平下是否显著,我们可以使用对数秩检验。

>>> res = stats.logrank(x=x, y=y)
>>> res.statistic
-2.73799
>>> res.pvalue
0.00618

p 值小于 1%,因此我们可以考虑数据为替代假设(两生存函数存在差异)反对无效假设的证据。