二分类模型评价指标-ROC&PRC

knitr::opts_chunk$set(echo = TRUE)

1. 符号

  先说明符号含义:

预测为正类预测为负类
实际为正类TPFN
实际为负类FPTN

符号标记:
TP—将正类预测为正类数
FN—将正类预测为负类数
FP—将负类预测为正类数
TN—将负类预测为负类数

  本文涉及到:

  1. TPR(True Positive Rate): 真阳性、同Recall
  2. FPR(False Positive Rate): 假阳性,所有确实为假的样本,错判成真的真的占比
  3. ROC(Receiver Operating Characteristic): 是TPR vs FPR的曲线
  4. PRC(Precision-Recall Curve): 展示的是Precision vs Recall的曲线

2. PRC

  以R中ROCR包里自带数据为例:
先求Recall、Precision、F1score

# 获取数据 --------------------------------------------------------------------
#以ROCR包里自带数据为例
data(ROCR.simple)
result <- data.frame(pre_prob=ROCR.simple$predictions,true_label=ROCR.simple$labels)
#概率大于0.5为正类,小于0.5负类
result <- within(result,{
  pre_label <- NULL
  pre_label[pre_prob>0.5] <- 1
  pre_label[pre_prob<=0.5] <- 0
  })
head(result)

#install.packages("gmodels")
library(gmodels)
CrossTable(x=result$true_label,y=result$pre_label,prop.chisq=FALSE)
#画PRC曲线:横轴Recall纵轴Precision.Threshold
#阈值的选取0.005为间隔,产生200个点
Precision <- NULL
Recall <- NULL
FPR <- NULL
for(i in seq(from=0,to=1,by=0.005)){
  #判为正类实际也为正类
  TP <- sum((result$pre_prob >= i) * (result$true_label == 1)) 
  #判为正类实际为负类
  FP <- sum((result$pre_prob >= i) * (result$true_label == 0))
  #判为负类实际为负类
  TN <- sum((result$pre_prob < i) * (result$true_label == 0)) 
  #判为负类实际为正类
  FN <- sum((result$pre_prob < i) * (result$true_label == 1)) 
  Precision <- c(Precision,TP/(TP+FP))
  Recall <- c(Recall,TP/(TP+FN))
  FPR <- c(FPR,FP/(FP+TN))
}
TPR <- Recall
length(Precision)
Precision[c(200,201)] <- 1#返回的概率没有大于0.995和1的,令其为1

返回结果:

1为正
Precision=79/(79+16)=0.832
Recall=79/(79+14)=0.849
F1=2*Precision*Recall/(Precision+Recall)=0.8404

对应的混淆矩阵:

knitr::include_graphics("../Picture/Pic03-ConfusionMatrix.png",dpi = 600)


PRC曲线:

#绘制PRC
library(ggplot2)
ggplot(data = NULL, mapping = aes(x = Recall, y = Precision)) +
  geom_point(alpha = 0.05) + scale_y_continuous(limits = c(0, 1)) +
  scale_x_continuous(limits = c(0, 1)) +
  geom_line()

PRC曲线越向(1,1)靠近,模型效果越好:

knitr::include_graphics("../Picture/Pic04-PRC.png",dpi = 600)

这里写图片描述

3. ROC曲线和AUC

3.1 ROC曲线

  纵轴为正阳性率,横轴为假阳性率。
  先明白为啥曲线必过(0,0)和(1,1)点:
1):阈值为1,则分类器返回的概率值大于1,才判为正。那么所有样本均判负,即TP=0、FP=0。则TPR=0/(FN+0)=0;FPR=0/(TN+0)=0
2):阈值为0,则分类器返回的概率值大于0,均判为正。那么所有样本均判正,即FN=0、TN=0。则TPR=TP/(TP+0)=0;FPR=FP/(FP+0)=0
原理是改变阈值,分别计算FPR和TPR,描点画图即可~
下面用R软件实现

#ROC曲线
##描点画图
ggplot(data = NULL, mapping = aes(x = Recall, y = FPR)) +
  geom_point() + scale_y_continuous(limits = c(0, 1)) +
  scale_x_continuous(limits = c(0, 1)) +
  geom_smooth(stat = "smooth", se = F)
#调包画图
library(ROCR) 
pred <- prediction(result$pre_prob,result$true_label)
performance(pred,'auc')@y.values #AUC值 
perf <- performance(pred,'tpr','fpr') 
plot(perf)

ROC曲线越靠近(0,1)点,分类效果越好。

knitr::include_graphics("../Picture/Pic05-Roc.png",dpi = 600)

这里写图片描述

3.2 AUC

  1. 直观解释
    AUC值为ROC曲线下面的面积,且越接近1说明分类效果越好
  2. Wilcoxon-Mann-Witney Test
    从正负样本各随机抽取一个样本Sample1、Sample2,并且分类器返回概率值为P1、P2
  3. AUC=P(P1>P2)
    其反应的是分类器对样本的排序能力,好的分类器应该返回正样本以更高概率值
3.2.1 计算方法
  • 假设有M个正样本N个负样本,按照分类器返回的概率值降序排序
  • 概率最大的值秩为rank_0(N+M)。设正样本中概率值最大的秩rank_1,那么比它概率小的正样本有M-1个,负样本rank_1-M个
  • 概率值次大的正样本的秩为rank_2,那么比它概率小的正样本有M-2个,负样本rank_2-M+1个
  • 概率值最小的正样本的秩为rank_M,那么比它概率小的正样本有0个,负样本rank_M-1个
  • 共可能产生N*M个样本对,其中满足的P1>P2的产品对有rank_1-M+rank_2-M+1+…+rank_M-1=sum(rank_i)-0.5(M+1)M

AUC=insipositiveclassrankinsiM(M+1)2MN A U C = ∑ i n s i ∈ p o s i t i v e c l a s s r a n k i n s i − M ∗ ( M + 1 ) 2 M ∗ N

3.2.2 R-Code

  前面我们说AUC=P(P1>P2),用R模拟,返现结果满足。

#1、调包求AUC 0.8341875
performance(pred,'auc')@y.values #AUC值 0.8341875
#2、模拟求AUC 0.83457
##即从正负样本中随机各抽取一个样本,比较大小,统计频率作为概率的近似
head(result)
postive_index <- which(result$true_label==1)
negative_index <- which(result$true_label==0)
postive_index_1 <- sample(postive_index,100000,replace = T)#有放回抽取100000个样本
negative_index_1 <- sample(negative_index,100000,replace = T)#有放回抽取100000个样本
sum(result$pre_prob[postive_index_1]>result$pre_prob[negative_index_1])/100000#0.83457,比较接近
#3、计算公式求AUC 0.8341875
order_result <- result[order(result$pre_prob),]
order_result$rank <-1:dim(order_result)[1]
table(order_result$true_label)#0:107 1:93
postive_rank <- which(order_result$true_label==1)
(sum(postive_rank)-0.5*93*94)/(107*93)

4. AUC等价Mann-Whitney U statistic

非参的定义:

knitr::include_graphics("../Picture/Pic06-Wmw.png",dpi = 600)

这里写图片描述

knitr::include_graphics("../Picture/Pic07-Wmw.png",dpi = 600)

这里写图片描述

knitr::include_graphics("../Picture/Pic08-Wmw.png",dpi = 600)

这里写图片描述
简述逻辑(未必清晰):
设共有N个负样本,M个正样本
从ROC的绘制上讲,横轴是FPC,即误判为正类数/N。可以考虑阈值是所有负样本的概率值,如果没有结(即没有概率一样的负样本),那么会有N个点。则可以把0-1平均分成N分,生成N个小矩形。如果有结,可以认为两个完全相等的矩形拼接成了一个大矩形。小矩形的宽为1/N,长为对应的TPR。AUC即这些矩形的面积和。
方便叙述,此时用负样本的秩计算。
对所有样本降序排序,负样本中概率最高的秩为rank_1,按照之前的计算,需要统计每个负样本前面共有多少正样本,可以生成符合要求的样本对。
设排序后的第i个负样本前面有Si个正样本,那么AUC=sum(Si)/MN
从面积上讲:每个小矩形的宽都是1/N,高是TPR=TP/M,当阈值为第i个负样本的概率时,TP=Si。面积和=sum(TPi)/MN
所以两者是等价的。
用R编程直接求面积,结果一毛一样~

# 4、直接求面积
#### 按照负样本的阈值,求TPR,完了直接对TPR求和,除以负样本个数
Precision_s <- NULL
Recall_s <- NULL
FPR_s <- NULL
for(i in result$pre_prob[negative_index]){
  #判为正类实际也为正类
  TP_s <- sum((result$pre_prob >= i) * (result$true_label == 1)) 
  #判为正类实际为负类
  FP_s <- sum((result$pre_prob >= i) * (result$true_label == 0))
  #判为负类实际为负类
  TN_s <- sum((result$pre_prob < i) * (result$true_label == 0)) 
  #判为负类实际为正类
  FN_s <- sum((result$pre_prob < i) * (result$true_label == 1)) 
  Precision_s <- c(Precision_s,TP_s/(TP_s+FP_s))
  Recall_s <- c(Recall_s,TP_s/(TP_s+FN_s))
  FPR_s <- c(FPR_s,FP_s/(FP_s+TN_s))
}
TPR_s <- Recall_s
sum(TPR_s)/length(negative_index)

主要参看下面文章,但是rank的表示似乎有点问题。没有完整的符号解释。

ROC分析当中的AUC和Mann-Whitney U statistic的关系

5. ROC VS PRC

  PRC和ROC的选择问题
感觉实际应用中,两个指标都要看~侧重点主要根据分类器的目的。比如:信贷风险预估中,看重的是recall的值,究竟能不能把可能逾期的用户识别出来。
总之,如果样本不平衡,可以通过PRC曲线看下模型适合有效(尽管它的AUC会很高)~调优时可以重点关注AUC的值。
看了各种回答,还是比较蒙蔽~

6.Ref

[1] ROC分析当中的AUC和Mann-Whitney U statistic的关系
[2] 机器学习和统计里面的auc怎么理解?
[3] 精确率、召回率、F1 值、ROC、AUC 各自的优缺点是什么?

                      2017-05-07 于杭州
                      2018-07-13 改于南京市建邺区新城科技园

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值