首页 > 编程知识 正文

roc曲线matlab如何实现,roc曲线代码python

时间:2023-05-03 16:52:40 阅读:266055 作者:2886

参考博客:
详解ROC/AUC计算过程
【机器学习笔记】:一文让你彻底理解准确率,精准率,召回率,真正率,假正率,ROC/AUC

一、准确率,精准率,召回率 1.TP、TN、FP、FN概念

P(Positive):代表1
N(Negative):代表0
T(True):代表预测正确
F(False):代表错误

以上四种情况可理解为:

先看 ①预测结果(P/N),再根据②实际表现对比预测结果,给出判断结果(T/F)。
如:
TP: 预测为1,预测正确,即实际1
FP: 预测为1,预测错误,即实际0
FN: 预测为0,预测错误,即实际1
TN: 预测为0,预测正确,实际0

2.准确率

准确率=(TP+TN)/(TP+TN+FP+FN)

虽然准确率可以判断总的正确率,但是在样本不平衡的情况下,并不能作为很好的指标来衡量结果。举个简单的例子,比如在一个总样本中,正样本占90%,负样本占10%,样本是严重不平衡的。对于这种情况,我们只需要将全部样本预测为正样本即可得到90%的高准确率,但实际上我们并没有很用心的分类,只是随便无脑一分而已。这就说明了:由于样本不平衡的问题,导致了得到的高准确率结果含有很大的水分。即如果样本不平衡,准确率就会失效。

3.精准率

精准率(Precision)又叫查准率,它是针对预测结果而言的,它的含义是在所有被预测为正的样本中实际为正的样本的概率,意思就是在预测为正样本的结果中,有多少把握可以预测正确,其公式如下:

精准率=TP/(TP+FP)

精准率和准确率看上去有些类似,但是完全不同的两个概念。精准率代表对正样本结果中的预测准确程度,而准确率则代表整体的预测准确程度,既包括正样本,也包括负样本。

4. 召回率

召回率(Recall)又叫查全率,它是针对原样本而言的,它的含义是在实际为正的样本中被预测为正样本的概率,其公式如下:

召回率=TP/(TP+FN)

召回率的应用场景: 比如拿网贷违约率为例,相对好用户,我们更关心坏用户,不能错放过任何一个坏用户。因为如果我们过多的将坏用户当成好用户,这样后续可能发生的违约金额会远超过好用户偿还的借贷利息金额,造成严重偿失。召回率越高,代表实际坏用户被预测出来的概率越高,它的含义类似:宁可错杀一千,绝不放过一个。

二、ROC/AUC的概念 1.灵敏度,特异度,真正率,假正率

在正式介绍ROC/AUC之前,我们还要再介绍两个指标,这两个指标的选择也正是ROC和AUC可以无视样本不平衡的原因。这两个指标分别是:灵敏度和(1-特异度),也叫做真正率(TPR)和假正率(FPR)

灵敏度(Sensitivity) = TP/(TP+FN) = 召回率

特异度(Specificity) = TN/(FP+TN)

其实我们可以发现灵敏度和召回率是一模一样的,只是名字换了而已。由于我们比较关心正样本,所以需要查看有多少负样本被错误地预测为正样本,所以使用(1-特异度),而不是特异度。

真正率(TPR) = 灵敏度 = TP/(TP+FN)

假正率(FPR) = 1- 特异度 = FP/(FP+TN)
下面是真正率和假正率的示意,可以发现TPR和FPR分别是基于实际表现1和0出发的,也就是说它们分别在实际的正样本和负样本中来观察相关概率问题。 正因为如此,所以无论样本是否平衡,都不会被影响。还是拿之前的例子,总样本中,90%是正样本,10%是负样本。我们知道用准确率是有水分的,但是用TPR和FPR不一样。这里,TPR只关注90%正样本中有多少是被真正覆盖的,而与那10%毫无关系,同理,FPR只关注10%负样本中有多少是被错误覆盖的,也与那90%毫无关系,所以可以看出:如果从实际表现的各个结果角度出发,就可以避免样本不平衡的问题了,这也是为什么选用TPR和FPR作为ROC/AUC的指标的原因。

或者也可以从另一个角度考虑:条件概率。我们假设X为预测值,Y为真实值。那么就可以将这些指标按条件概率表示:
精准率 = P(Y=1 | X=1)

召回率 = 灵敏度 = P(X=1 | Y=1)

特异度 = P(X=0 | Y=0)

从上面三个公式看到:如果先以实际结果为条件(召回率,特异度),那么就只需考虑一种样本,而先以预测值为条件(精准率),那么我们需要同时考虑正样本和负样本。所以先以实际结果为条件的指标都不受样本不平衡的影响,相反以预测结果为条件的就会受到影响。

2.ROC(接受者操作特征曲线)

ROC(Receiver Operating Characteristic)曲线,又称接受者操作特征曲线。该曲线最早应用于雷达信号检测领域,用于区分信号与噪声。后来人们将其用于评价模型的预测能力,ROC曲线是基于混淆矩阵得出的。

ROC曲线中的主要两个指标就是真正率假正率,上面也解释了这么选择的好处所在。其中横坐标为假正率(FPR),纵坐标为真正率(TPR),下面就是一个标准的ROC曲线图。
TPR越高,同时FPR越低(即ROC曲线越陡),那么模型的性能就越好

3.AUC(曲线下的面积)

AUC计算方法

为了计算 ROC 曲线上的点,可以使用不同的分类阈值多次评估逻辑回归模型,但这样做效率非常低。幸运的是,有一种基于排序的高效算法可以提供此类信息,这种算法称为曲线下面积(Area Under Curve)

比较有意思的是,如果连接对角线,它的面积正好是0.5。对角线的实际含义是:随机判断响应与不响应,正负样本覆盖率应该都是50%,表示随机效果。 ROC曲线越陡越好,所以理想值就是1,一个正方形,而最差的随机判断都有0.5,所以一般AUC的值是介于0.5到1之间的。

AUC的一般判断标准
0.5 - 0.7: 效果较低,但用于预测股票已经很不错了

0.7 - 0.85: 效果一般

0.85 - 0.95: 效果很好

0.95 - 1: 效果非常好,但一般不太可能

三、Python实现

使用Python的sklearn.metrics.roc_curve可以计算值并画出ROC曲线

1.roc_curve简单介绍 (1)重要参数

y_true:真实结果数据,数据类型是数组
y_score:预测结果数据,可以是标签数据也可以是概率值,数据类型是形状 与y_true一致的数组
pos_label:默认为None,只有当标签数据如{0,1}、{-1,1}二分类数据才能默认;否则需要设置正样本值

(2)返回结果

返回三个数组结果分别是FPR(假正率),TPR(召回率),threshold(阈值)

2. 第一种情形:y_score是标签数据 (1)例子 //python 代码y_true=np.array([0, 0, 0, 1, 1, 0, 0, 0, 1, 0])y_score=np.array([0, 0, 0, 1, 1, 0, 0, 0, 0, 0])fpr,tpr,threshold=roc_curve(y_true,y_score)

返回结果:

threshold:array([2, 1, 0])tpr:array([0. , 0.66666667, 1. ])fpr:array([0., 0., 1.]) (2)解释 threshold返回的结果是y_score内的元素去重后加入一个‘最大值+1’的值降序排序后组成的数据,每一个元素作为阈值,数据类型是一维数组。比如:y_score=np.array([0, 1, 2,0,3,1])对应的threshold=np.array([4, 3, 2,1,0])当index=0,阈值等于threshold[0]=2。此时,假定y_score中所有大于等于2的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因没有大于等于2的值,所以TP和FP都为0,即tpr[0]=0/3=0.0,fpr[0]=0/7=0.0当index=1,阈值等于threshold[1]=1。此时,假定y_score中所有大于等于1的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于1的数有2个,所以TP=2和FP=0,即tpr[1]=2/3=0.66666667,fpr[1]=0/7=0.0当index=2,阈值等于threshold[2]=0。此时,假定y_score中所有大于等于0的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于0的数有10个,所以TP=3和FP=7,即tpr[2]=3/3=1.0,fpr[2]=7/7=1.0所以,最终结果:tpr=array([0., 0.66666667, 1.]),fpr=array([0., 0., 1.]) 3.第二种情形:y_score是概率值 (1)例子 //python 代码y_true=np.array([0,0,1,1])y_score=np.array([0.1,0.4,0.35,0.8]) # 概率值选择的是正类的概率fpr,tpr,threshold=roc_curve(y_true,y_score)

返回结果:

threshold:array([1.8 , 0.8 , 0.4 , 0.35, 0.1])tpr:array([0. , 0.5, 0.5, 1. , 1.])fpr:array([0. , 0. , 0.5, 0.5, 1. ]) (2)解释 当index=0,阈值等于threshold[0]=1.8。此时,假定y_score中所有大于等于1.8的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因没有大于等于1.8的值,所以TP和FP都为0,即tpr[0]=0/2=0.0,fpr[0]=0/2=0.0当index=1,阈值等于threshold[1]=0.8。此时,假定y_score中所有大于等于1的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于0.8的数有1个,刚好y_true中该位置元素值为1,所以TP=1和FP=0,即tpr[1]=1/2=0.5,fpr[1]=0/2=0.0当index=2,阈值等于threshold[2]=0.4。此时,假定y_score中所有大于等于0.4的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于0.4的数有2个,所以TP=1和FP=1,即tpr[2]=1/2=0.5,fpr[2]=1/2=0.5当index=3,阈值等于threshold[3]=0.35。此时,假定y_score中所有大于等于0.35的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于0.35的数有3个,所以TP=2和FP=1,即tpr[3]=2/2=1.0,fpr[3]=1/2=0.5当index=4,阈值等于threshold[4]=0.1。此时,假定y_score中所有大于等于0.1的元素对应index在y_true中的样本为正样本,其他为负样本,然后与y_true对应元素对比组成混淆矩阵,因大于等于0.1的数有4个,所以TP=2和FP=2,即tpr[4]=2/2=1.0,fpr[4]=2/2=1.0所以,最终结果:tpr=array([0. , 0.5, 0.5, 1. , 1.]),fpr=array([0. , 0. , 0.5, 0.5, 1. ]) 4.画ROC曲线 fpr, tpr, threshold = roc_curve(y_true_, y_pred_)roc_auc = auc(fpr,tpr) # 准确率代表所有正确的占所有数据的比值print('roc_auc:', roc_auc)lw = 2plt.subplot(5,3,s+1)plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.2f)' % roc_auc) # 假正率为横坐标,真正率为纵坐标做曲线plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')plt.xlim([0.0, 1.0])plt.ylim([0.0, 1.0])plt.xlabel('1 - specificity')plt.ylabel('Sensitivity')plt.title('ROC', y=0.5)plt.legend(loc="lower right")plt.show()

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。