「R」ROC三剑客(一)使用R语言手撕ROC曲线

2020-05-08 24287动手实验室

之前因工作需要绘制ROC曲线,所以对该曲线的计算细节进行了一番摸索。刚开始我搜索ROC曲线一般跟机器学习相关联,导致我对它的概念有了曲解,理所当然地以为它只是一个用于机器学习的分类器评估标准,所以在绘制曲线前应当使用逻辑回归等模型对数据建模分析。实则不然,ROC曲线适用于任何判断0-1类型(真假、成功失败等二分类)响应结果阈值分割效果的评估。这个道理我在2018年前后是不懂的,当时一想到画ROC、计算AUC就懵逼。

下面一段引用非常清楚地描述了ROC原理和应用。

对于0,1两类分类问题,一些分类器得到的结果往往不是0,1这样的标签,如神经网络得到诸如0.5,0.8这样的分类结果。这时,我们人为取一个阈值,比如0.4,那么小于0.4的归为0类,大于等于0.4的归为1类,可以得到一个分类结果。同样,这个阈值我们可以取0.1或0.2等等。取不同的阈值,最后得到的分类情况也就不同。如下面这幅图:

ROC1_1

蓝色表示原始为负类分类得到的统计图,红色表示原始为正类得到的统计图。那么我们取一条直线,直线左边分为负类,直线右边分为正类,这条直线也就是我们所取的阈值。阈值不同,可以得到不同的结果,但是由分类器决定的统计图始终是不变的。这时候就需要一个独立于阈值,只与分类器有关的评价指标,来衡量特定分类器的好坏。还有在类不平衡的情况下,如正样本有90个,负样本有10个,直接把所有样本分类为正样本,得到识别率为90%,但这显然是没有意义的。如上就是ROC曲线的动机。

在R里面,有ROCR与专门的机器学习包mlr(现在是mlr3了)可以进行建模和绘制ROC曲线,以及相关参量的计算。实际上,不需要使用任何模型,也可以绘制ROC曲线,因为ROC曲线的绘制就是选择阈值与计算当前阈值下假阳性率与真阳性率变化的过程。

上述提到的两个包使用有些复杂,实际上我要用的也不是它们,关于ROC的计算,仔细思考写个程序就能搞定。我们接下来使用R语言手撕AUC计算。

这里的核心是计算假阳性、真阳性率,所以首先要计算下方混淆矩阵中的各个参数。

ROC1_2
ROC1_3
ROC1_4
ROC1_5

上面函数的运行需要保证tidyverse包已经安装,写法遵从tidyverse语法,涉及不少管道操作,如果你只想使用,直接拷贝运行即可,如果想要理解过程,需要《dplyr使用和编程》(列举一篇笔记)的一些知识。略微讲解一下使用:

args(calcROC)function (.data, predict_var, target, group_var, positive = "success") 

函数有5个参数,第一个是包含数据的数据框;第二个是预测变量,一个数值向量;第三个是目标变量,包含0-1信息(成功或失败,等等);第四个是一个分组参数,一般我们会比较两组或多组ROC曲线的差异;第五个是给出成功(或1)是用什么指定的,比如目标变量中success指代成功。结果会返回一个数据框:

ROC1_6
ROC1_7

注意这里函数调用时写法符合dplyr,相关参数可没有打引号,注意下~

左边第一列不用管,是一个无意义的行名,结果共有7列,而画图只需要最后的三列。每个组都有一行是伪造的,用于填充图像中的(0,0)点,也即阈值取无穷大时。

调用ggpubr包画图:

ggpubr::ggline(data = calcROC(dat, mut, isBenefit, Gender), x = "fpr", y = "tpr", linetype = "Group", shape = "Group")

ROC1_8

可以看到,这里的 ROC 图很不美丽,但它是对的,而且能用,这是关键。我之前一篇发表的工作《The predictive power of tumor mutational burden in lung cancer immunotherapy response is influenced by patients’ sex》很多的图都是基于这个做出来的。比如 Figure 3。

ROC1_9

当然图还是丑。。。不过事情先做成,后做好,作图是需要经验积淀的,也不是每一个人都是 Y 叔,画图能出神入化。这篇文章理解原理和如何计算和核心,读者理解后再修炼其他两剑事半功倍~

▍本文版权(包括图片及文字)属于“优雅R”(微信公众号:elegant-r),禁止二次转载,如需转载请联系w_shixiang@163.com

上一篇下一篇