ROC阳性结果还是阴性结果?
“医学和生信笔记,专注R语言在临床医学中的使用、R语言数据分析和可视化。主要分享R语言做医学统计学、临床研究设计、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。
💡专注R语言在🩺生物医学中的使用
关于ROC曲线的内容很重要,无论是在医学统计、机器学习,还是临床预测模型中,都是很重要的内容,大家务必要掌握!
大家都知道ROC曲线的横坐标是假阳性率,纵坐标是真阳性率,根据数据,我们可以计算很多个假阳性率和真阳性率,然后就可以在坐标轴上画出很多个点,把这些点连接成线就是ROC曲线了。
那这些横纵坐标的值到底是怎么计算的呢?
假如,我想根据ca125的值判定一个人到底有没有肿瘤,找了10个肿瘤患者,20个非肿瘤患者,都给他们测一下ca125,这样就得到了30个ca125的值。
set.seed(20220840)
ca125_1 <- c(rnorm(10,80,20),rnorm(20,50,10))
# 30个人的ca125的值如下
ca125_1
## [1] 51.88470 82.45907 113.66834 63.49476 98.29077 63.27374 74.25079
## [8] 80.22945 83.01740 99.17105 42.52889 54.56804 48.88383 65.67865
## [15] 44.73153 45.99028 55.82554 42.79242 60.84917 64.80764 51.11468
## [22] 43.40118 47.03850 44.75943 68.34163 60.83829 53.32599 59.92225
## [29] 46.46360 30.02914
假定前10个人是肿瘤,后20个人是非肿瘤。
outcome <- c(rep(c("肿瘤","非肿瘤"),c(10,20)))
outcome
## [1] "肿瘤" "肿瘤" "肿瘤" "肿瘤" "肿瘤" "肿瘤" "肿瘤" "肿瘤"
## [9] "肿瘤" "肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤"
## [17] "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤"
## [25] "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤" "非肿瘤"
df <- data.frame(`outcome`=outcome,
`ca125`=ca125_1
)
psych::headtail(df)
## outcome ca125
## 1 肿瘤 51.88
## 2 肿瘤 82.46
## 3 肿瘤 113.67
## 4 肿瘤 63.49
## ... <NA> ...
## 27 非肿瘤 53.33
## 28 非肿瘤 59.92
## 29 非肿瘤 46.46
## 30 非肿瘤 30.03
现在如果我们设置ca125>60,判断为肿瘤,ca125≤50判断为非肿瘤,就能得到如下的结果:
df1 <- transform(df, pred = ifelse(ca125>60,"猜他是肿瘤","猜他不是肿瘤"))
df1
## outcome ca125 pred
## 1 肿瘤 51.88470 猜他不是肿瘤
## 2 肿瘤 82.45907 猜他是肿瘤
## 3 肿瘤 113.66834 猜他是肿瘤
## 4 肿瘤 63.49476 猜他是肿瘤
## 5 肿瘤 98.29077 猜他是肿瘤
## 6 肿瘤 63.27374 猜他是肿瘤
## 7 肿瘤 74.25079 猜他是肿瘤
## 8 肿瘤 80.22945 猜他是肿瘤
## 9 肿瘤 83.01740 猜他是肿瘤
## 10 肿瘤 99.17105 猜他是肿瘤
## 11 非肿瘤 42.52889 猜他不是肿瘤
## 12 非肿瘤 54.56804 猜他不是肿瘤
## 13 非肿瘤 48.88383 猜他不是肿瘤
## 14 非肿瘤 65.67865 猜他是肿瘤
## 15 非肿瘤 44.73153 猜他不是肿瘤
## 16 非肿瘤 45.99028 猜他不是肿瘤
## 17 非肿瘤 55.82554 猜他不是肿瘤
## 18 非肿瘤 42.79242 猜他不是肿瘤
## 19 非肿瘤 60.84917 猜他是肿瘤
## 20 非肿瘤 64.80764 猜他是肿瘤
## 21 非肿瘤 51.11468 猜他不是肿瘤
## 22 非肿瘤 43.40118 猜他不是肿瘤
## 23 非肿瘤 47.03850 猜他不是肿瘤
## 24 非肿瘤 44.75943 猜他不是肿瘤
## 25 非肿瘤 68.34163 猜他是肿瘤
## 26 非肿瘤 60.83829 猜他是肿瘤
## 27 非肿瘤 53.32599 猜他不是肿瘤
## 28 非肿瘤 59.92225 猜他不是肿瘤
## 29 非肿瘤 46.46360 猜他不是肿瘤
## 30 非肿瘤 30.02914 猜他不是肿瘤
这样就能得出一个四格表:
xtabs(~outcome+pred,data = df1)
## pred
## outcome 猜他不是肿瘤 猜他是肿瘤
## 非肿瘤 15 5
## 肿瘤 1 9
根据这个四格表我们就能算出目前的真阳性率和假阳性率:
真阳性率:猜他是肿瘤猜对的人数 / 所有肿瘤人数
假阳性率:猜他是肿瘤猜错的人数 / 所有非肿瘤人数
真阳性率 = 9 / (1+9) = 0.9
假阳性率 = 5 / (15+5) = 0.25
一个阈值就能算出1个真阳性率和假阳性率,多找几个阈值就能算出多个率,把这些率画在坐标轴里,再连成线,就是ROC曲线了。
此时,我们计算的是确定是肿瘤的真阳性率和假阳性率,画出来的也是确定是肿瘤的ROC曲线。
现在大家可以思考一个问题,如果我想知道的是确定不是肿瘤的能力,那算出来的东西还一样吗?
反过来可以吗?
一般情况下我们感兴趣的是确定是肿瘤的能力,此时真阳性率和假阳性率的计算如下:
# 首先是获得四格表
xtabs(~outcome+pred,data = df1)
## pred
## outcome 猜他不是肿瘤 猜他是肿瘤
## 非肿瘤 15 5
## 肿瘤 1 9
真阳性率:猜他是肿瘤猜对的人数 / 所有肿瘤人数
假阳性率:猜他是肿瘤猜错的人数 / 所有非肿瘤人数
真阳性率 = 9 / (1+9) = 0.9
假阳性率 = 5 / (15+5) = 0.25
但是如果我们感兴趣的是确定为非肿瘤的能力呢?
# 此时四格表还是这个四格表
xtabs(~outcome+pred,data = df1)
## pred
## outcome 猜他不是肿瘤 猜他是肿瘤
## 非肿瘤 15 5
## 肿瘤 1 9
但是真阳性率和假阳性率的计算已经变了!
假阳性率:猜他不是肿瘤猜错的人数 / 所有肿瘤人数
真阳性率:猜他不是肿瘤猜对的人数 / 所有非肿瘤人数
假阳性率 = 1 / (1+9) = 0.1
真阳性率 = 15 / (15+5) = 0.75
此时再多取几个阈值,画出来的就是阴性结果的ROC曲线。
不知道大家平时有没有关注过这个问题呢?
在R语言中很多画ROC曲线的包都会提供一个参数,让你可以自由选择ROC哪一个结果,一般默认都是阳性结果的ROC,比如这里的有肿瘤,如果你不放心,可以手动指定,想计算谁就计算谁!
咨询交流等,欢迎加入🐧QQ交流群:613637742
往期推荐