ROC分析时一定要告诉R分析谁

2020-04-28 10:12:59 浏览数 (3)

嗨!大家好,我是一棵树,这是我第一次在解螺旋发文,还是蛮激动的。下面就开始吧! 今天的主题是:ROC分析时一定要告诉R分析谁 用到的软件是:R语言 用到的R包是:pROC和ROCit

1.安装R包

install.packages('pROC') install.packages('ROCit')

2.构建数据

我们先构建2个连续变量score1和score2,1个2分类变量class。class变量有2个数值0和1,0代表阴性结果,1代表阳性结果。

score1=c(0.830410619,0.455829518,0.058478492, 0.729325234,0.831480755,0.134660431, 0.695320049,0.662420877,0.528904992, 0.371757106,0.87803265,0.705919705, 0.740182936,0.060545256,0.891066853, 0.568020037,0.379067286) score2=c(0.376703255,0.694968207,0.066650344, 0.261298118,0.079832816,0.005758134, 0.433320986,0.211177625,0.68847034, 0.085216767,0.452439458,0.054711128, 0.719909102,0.653851262,0.500626397, 0.380789783,0.430002115) class=c(1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0)

3.常规的ROC分析

现在,我们来做score1和class的ROC分析,看一下他们的AUC

使用pROC包

pROC::roc(predictor = score1,response = class)

## Setting levels: control = 0, case = 1

## Setting direction: controls < cases

## ## Call: ## roc.default(response = class, predictor = score1) ## ## Data: score1 in 10 controls (class 0) < 7 cases (class 1). ## Area under the curve: 0.4714

使用ROCit包

ROCit::rocit(score = score1,class = class)$AUC

## [1] 0.4714286

两个包的AUC结果一致,都是0.4714。这种做法也是我们常规的做法。

4.不一致的ROC分析结果

奇怪的事情马上就要发生了! 现在,我们再对score2和class做ROC分析,看一下他们的AUC

使用pROC包

pROC::roc(predictor = score2,response = class)

## Setting levels: control = 0, case = 1

## Setting direction: controls > cases

## ## Call: ## roc.default(response = class, predictor = score2) ## ## Data: score2 in 10 controls (class 0) > 7 cases (class 1). ## Area under the curve: 0.6857

使用ROCit包

ROCit::rocit(score = score2,class = class)$AUC

## [1] 0.3142857

这个时候pROC包计算的AUC是0.6857,而ROCit包计算的结果是0.3142,两个差别很大啊。这是咋回事?相同的命令,换个数据结果就不一样了?

5.为什么2个包的结果会矛盾

我们再回头看,使用pROC包分析score1和class时,有这样一段提示

## Setting direction: controls < cases

同样使用pROC包分析score2和class时,也有这样一段提示

## Setting direction: controls > cases

同样的class,两次计算的方向竟然不同,第一次是controls < cases,而第二次是controls > cases,这个是什么意思呢?

controls < cases:表示controls组的中位数小于cases组的中位数,pROC包对cases组进行ROC分析,计算cases组的AUC。 controls > cases:表示controls组的中位数大于cases组的中位数,pROC包对controls组进行ROC分析,计算controls组的AUC。

我们先来看一下score1在class两组的中位数。

c(controls=median(score1[class==0]), cases=median(score1[class==1]))

## controls cases ## 0.6152205 0.6953200

再来看一下score2在class两组的中位数。

c(controls=median(score2[class==0]), cases=median(score2[class==1]))

## controls cases ## 0.4412208 0.2612981

谜底终于揭开:pROC包在自动进行ROC分析的时候,是根据两组中位数的大小来决定分析哪组的,谁的中位数大,就分析谁,就计算谁的AUC!

6.带来的问题

这样会带来很严重的问题! 很多时候,我们进行ROC分析时,默认都是去计算class=1那组,也就是阳性组的AUC,而class=0,被我们默认当成了阴性组,也就是参考组。在ROCit包中就是这样的,但是在大名鼎鼎的pROC包中,ROC分析的依据却是中位数的大小。这一点千万要注意。 如果你用pROC包做ROC分析,那么接下来的AUC和cutoff value都是要注意的,如果你不事先设置参考,得到的结果可能就搞不清楚是阴性组的AUC还是阳性组的AUC,仅仅是中位数高的那组的AUC,而你默认都是当成阳性组的AUC。

千万要注意这一点!

7.告诉R去ROC谁

在pROC::roc()函数中,有2个参数是需要我们设置的levels和direction,levels表示结局变量中的数值水平,direction的值是大于号>或小于号<,表示levels的第1个数值和第2个数值的大小关系。 现在我们给levels赋值0和1,direction赋值小于号<,表示0组的中位数小于1组的中位数,让pROC始终ROC1组,AUC1组。

pROC::roc(predictor = score2,response = class, levels = c(0,1), direction='<')

## ## Call: ## roc.default(response = class, predictor = score2, levels = c(0, 1), direction = "<") ## ## Data: score2 in 10 controls (class 0) < 7 cases (class 1). ## Area under the curve: 0.3143

这个时候得到结果0.314,和ROCit包的结果一致了。 在ROCit::rocit()函数中,我们通过给negref参数赋值0,设置ROC分析的阴性参考

ROCit::rocit(score = score2,class = class, negref = 0)$AUC

## [1] 0.3142857

8.总结

ROC分析时一定要设置结局的阴性参考! ROC分析函数,不提供设置参考的参数,可以考虑丢弃了!

0 人点赞