三种时间依赖的ROC

诊断模型的ROC是大家最熟悉的,一组二分类的真实标签,一组风险分值,不同的cutoff下有不同的灵敏度和特异性,就能画出ROC曲线。

生存分析一般建立Cox模型,根据Cox模型也会有一组风险分值,生存结局也是一个二分类的标签,但病例多了时间的信息。

三种不同的定义来估计删失事件的时间依赖的敏感性和特异性,即(1)cumulative/dynamic累积/动态(C/D),(2)incident/dynamic事件/动态(I/D)和(3) incident/static事件/静态 (I/S)。不同的定义下,灵敏度和特异性的计算不一样。其中C/D比I/D和I/S更具有临床相关性,在临床中普遍使用。

t: 目标时间,t* 固定的随访时间,c 阈值,A-F为研究中的个体病例,其中ABC的指标高于c,DEF个体的指标小于c,实心圆表示发生事件的个体,空心圆表示Censored个体。

图a,C/D、I/D、I/S中的相对于基线时间点的实验和对照个体说明,图b,I/S(纵向)的说明

Cumulative sensitivity and dynamic specificity (C/D)

$$ \begin{array}{l} S{e}^C\left( c, t\right)= P\left({X}_i> c\Big|{T}_i\le t\right)\\ {} S{p}^D\left( c, t\right)= P\left({X}_i\le c\Big|{T}_i> t\right)\\ {} AU{C}^{C, D}(t)= P\left({X}_i>{X}_j\Big|{T}_i\le t,{T}_j> t\right), i\ne j.\end{array} $$

cumulative/dynamic(C/D)中cumulative是指Cumulative sensitivity,dynamic是指dynamic specificity。C/D是用的最广泛的ROC模型。

灵敏度:生存时间小于t的人群之中,Xi大于阈值c的人群(A和B个体)所占总体(A、B和E)的比例

特异度:生存时间大于t的人群之中,Xi小于等于阈值c的人群(D和F)所占总体(C,D和F)的比例

用二分类模型来类比,时间ROC,在选定特定时间点(比如1年、3年或者5年)时,不同的阈值c可以将队列人群分成高于c的一组(高风险,认为发生了死亡/事件)和小于等于c(低风险,认为没有发生死亡/事件),但这个时间点有真实的死亡或者事件的标签,于是可以计算在特定时间点特定c时的灵敏度和特异性,进行画ROC计算AUC。所以文献中经常看到1yr, 3yr, 5yr ROC的图,有了ROC的图,其实也可以画DCA进行DCA分析。

Incident sensitivity and dynamic specificity (I/D)

$$ \begin{array}{l} S{e}^I= P\left({X}_i> c\Big|{T}_i= t\right)\\ {} S{p}^D= P\left({X}_i\le c\Big|{T}_i> t\right)\\ {} AU{C}^{I, D}(t)= P\left({X}_i>{X}_j\Big|{T}_i= t,{T}_j> t\right), i\ne j.\end{array} $$ 灵敏度:在生存时间等于t的人群中,Xi大于阈值c的人群所占的比例

特异度:生存时间大于t的人群中,Xi小于等于阈值c的人群所占的比例

Incident sensitivity and static specificity (I/S)

$$ \begin{array}{l} S{e}^I= P\left({X}_i> c\Big|{T}_i= t\right)\\ {} S{p}^S= P\left({X}_i\le c\Big|{T}_i> t^{*}\right).\end{array} $$

灵敏度:在生存时间等于t的人群中,Xi大于阈值c的人群所占的比例

特异度:生存时间大于t*(非t,参考上图)的人群中,Xi小于等于阈值c的人群所占的比例

时间ROC分析工具

survivalROC, timeROC,tdROC、timereg、risksetROC、survAUC

ROC和AUC

用mayo数据集为例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
library(timeROC)
library(survivalROC)
library(survival)

data(mayo)

time_roc_res <- timeROC(
  T = mayo$time,
  delta = mayo$censor,
  marker = mayo$mayoscore5,
  cause = 1,
  weighting="marginal",
  times = c(3 * 365, 5 * 365, 10 * 365),
  ROC = TRUE,
  iid = TRUE
)

得到结果后,可以通过time_roc_res$TP和time_roc_res$FP数据用ggplot2画,也可以用timeROC提供的plot函数来画。

1
2
3
4
5
plot(time_roc_res, time=3 * 365, col = "red", title = FALSE)  
plot(time_roc_res, time=5 * 365, add=TRUE, col="blue") 
plot(time_roc_res, time=10 * 365, add=TRUE, col="green") 
legend("bottomright",c("3 Years" ,"5 Years", "10 Years"),
       col=c("red", "blue", "green"), lty=1, lwd=2)

查看AUC的值,可以看到3年,5年,10年的AUC值为0.898, 0.915, 0.857,根据不同时间点的AUC,可以分析模型预测的分值在哪个时间点性能最好。

1
2
3
> time_roc_res$AUC
   t=1095    t=1825    t=3650 
0.8982790 0.9153621 0.8576153

为了重复这个AUC,我自己也手动粗略的计算了一遍,5年的AUC稍微不一样,3年和10年的AUC基本是一致的。当然自己计算的不准确,可能timeROC还有会算法上的优化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> risk = mayo$mayoscore5
> time = mayo$time

> label.3y  = mayo$censor
> label.5y  = mayo$censor
> label.10y = mayo$censor

# 特定时间点事,发生事件的情况,如果时间点之后发生,其实说明在这个时间点并没有发生时间。
# 3年
> label.3y[time  >  3 * 365] = 0
> roc_obj <- pROC::roc(label.3y, risk, quiet=TRUE)
> auc(roc_obj)

Area under the curve: 0.898

# 5年
> label.5y[time  >  5 * 365] = 0
> roc_obj <- pROC::roc(label.5y, risk, quiet=TRUE)
> auc(roc_obj)

Area under the curve: 0.903

# 10年
> label.10y[time > 10 * 365] = 0
> roc_obj <- pROC::roc(label.10y, risk, quiet=TRUE)
> auc(roc_obj)

auc(roc_obj)
Area under the curve: 0.8533

参考

https://www.bioinfo-scrounger.com/archives/Time-dependent-ROC/

https://www.sohu.com/a/498935870_120377538

https://www.51xxziyuan.com/58/3703.html

https://bmcmedresmethodol.biomedcentral.com/articles/10.1186/s12874-017-0332-6

####################################################################

#版权所有 转载请告知 版权归作者所有 如有侵权 一经发现 必将追究其法律责任

#Author: Jason

#####################################################################