1.ROC-AUC 和PR-AUC定义
AUC: 随机抽出一对样本(一个正样本,一个负样本),然后用训练得到的分类器来对这两个样本进行预测,预测得到正样本的概率大于负样本概率的概率。
ROC-AUC 指的是 ROC 曲线下的面积,通过在【0,1】范围内设置阈值来计算对应的TPR和FPR,最终将所有的点连起来构成ROC曲线。
PR-AUC 的构造和上述过程基本一致,只是需要再计算出 Precision 和 Recall ,以precision(精准率)和recall(召回率)这两个为变量而做出的曲线,其中recall为横坐标,precision为纵坐标。设定一系列阈值,计算每个阈值对应的recall和precision,即可计算出PR曲线各个点。
关于AUC的计算可参考: (5条消息) AUC的计算方法_SCUT_Sam-CSDN博客_auc计算公式
2.ROC-AUC 和PR-AUC的使用场景
所以当类别相对来说较均衡时,可以使用 ROC-AUC,当类别极其不均衡时使用 PR-AUC 较好。
从各自两个指标来看,TPR 和 FPR 分别聚焦于模型对正样本和负样本的分类能力,而 Precision 和 Recall 都是针对正样本的指标,没有考虑负样本。所以当我们希望模型在正负样本上都能表现较好时使用 ROC-AUC 衡量,如果我们只关注模型对正样本的分辨能力使用 PR-AUC 更好
3.程序代码如何实现RP-AUC、ROC-AUC的计算, 使用sklearn库。
####可以使用sklearn.metrics.precision_recall_curve 来计算PR曲线
from sklearn.metrics import precision_recall_curve,auc,accuracy_score
import numpy as np
from sklearn import metrics
label=[1,0,0,0,1,0]
prob=[1,0,0,1,0,0]
precision, recall, thresholds = precision_recall_curve(ture_lab,pre_lab)
###使用AUC函数计算出PR-auc值
auc_precision_recall = auc(recall, precision)
####'''计算ROC-AUC值'''#####
roc_auc=metrics.roc_auc_score(label,prob)
4.遇到的问题
1)ROC-AUC 计算时,如果遇到“ValueError: Only one class present in y_true. ROC AUC score is not defined in that case.”问题:
可能是因为label只有一种类型导致的,数据过分不平衡,针对这种情况:
如果是用于模型训练中的测试集,要在脚本中事先做好label只有一类情况的定义
如果是用于模型验证中的验证集,也是要实现做好实际类别是否只有一类的判断,然后做相应的计算。
报错示例如下:
label=[1,1,1,1,1,1]
prob=[0,0,0,0,0,0]
报错如下:
解决此问题的方法:
避免数据不平衡情况,或者在代码中加入判断行,可以使用try :
import numpy as np
from sklearn.metrics import roc_auc_score
label=[1,1,1,1,1,1]
prob=[0,0,0,0,0,0]
try:
roc_auc=roc_auc_score(label, prob)
except ValueError:
pass ##或者其它定义,例如roc_auc=0
2)计算PR-ROC时,隐藏bug,如果label中只有一类的数据,计算PR-RIC时并不报错,但是会计算错误
示例如下:
label=[1,1,1,1,1,1]
prob=[0,0,0,0,0,0]
'''计算PR曲线的AUC值'''
precision, recall, _thresholds = metrics.precision_recall_curve(label, prob)
print("recall","precison:",recall,precision)
print("PR-AUC:",metrics.auc(recall, precision))
print("label:",label)
print("prob",prob)
错误结果示例:
当真实类别只有“1”,预测类别全是“0”,出现PR-AUC计算为1的情况,实际是不对的结果,但是并不会报错。
解决此问题的方法:
避免数据不平衡情况,或者在代码中加入判断行,进行极端条件警示和定义即可。