【机器学习】ROC曲线以及AUC面积的原理(理论+图解)

简介: 【机器学习】ROC曲线以及AUC面积的原理(理论+图解)

简 介:下面是我在学习时候的记录并加上自己的理解。本文意在记录自己近期学习过程中的所学所得,如有错误,欢迎大家指正。

 

关键词:Python、机器学习

一、什么是ROC曲线

 我们通常说的ROC曲线的中文全称叫做接收者操作特征曲线(receiver operating characteristic curve),也被称为感受性曲线。

该曲线有两个维度,横轴为fpr(假正率),纵轴为tpr(真正率)

  • 准确率(accuracy):(TP+TN)/ ALL =(3+4)/ 10 准确率是所有预测为正确的样本除以总样本数,用以衡量模型对正负样本的识别能力。
  • 错误率(error rate):(FP+FN)/ ALL =(1+2)/ 10 错误率就是识别错误的样本除以总样本数。
  • 假正率(fpr):FP / (FP+TN) = 2 / (2+4)假正率就是真实负类中被预测为正类的样本数除以所有真实负类样本数。
  • 真正率(tpr):TP / (TP+FN)= 3 / (3+1)真正率就是真实正类中被预测为正类的样本数除以所有真实正类样本数。

这个曲线是怎么画出来的呢?

这幅曲线的每个点都对应一个(fpr,tpr),看过之前混淆矩阵的话,感觉一堆数据好像最终只能算出一个fpr和tpr,那是如何获得这么多的点的呢?

我们y会有一个预测为正类的概率,我们会将这个概率从大到小进行排序,然后再每个概率阈值的情况下进行将数据分类,能够计算出一组新的fpr和tpr,这样就会再不同的概率阈值下计算出多组点。

二、AUC面积

 上面说了什么是ROC曲线,横轴为fpr,纵轴为tpr,fpr就是假正率,就是真实的负类被预测为正类的样本数除以所有真实的样本数,而tpr是真正率,是正式的正类被预测为正类的数目除以所有正类的样本数,所以我们的目标就是让假正率越小,真正率越大(负样本被误判的样本数越少,正样本被预测正确的样本数越大),那么对应图中ROC曲线来说,我们希望的是fpr越小,tpr越大,即曲线越靠近左上方越好,那么下面的面积也就成为了我们的衡量指标,俗称AUC(Area Under Curve)。

解释下图中四个点的含义:

  • (0,0):该点代表fpr和tpr都为0,也就是说此时负类样本全部预测正确,而正类样本全部预测错误。
  • (0,1):该点代表fpr为0,tpr为1,就是说此时负类样本全部预测正确,正类样本也全部预测正确,这也验证了我们上面说曲线越靠近左上方越好。
  • (1,0):该点代表fpr为1,tpr为0,即负类样本全部被预测为正类样本,而正类样本全部被预测为负类样本,这是最坏的情况,也就对应了图中的右下角。
  • (1,1):该点代表fpr为1,tpr为1,即负类样本全部预测错误,但是正类样本全部预测正确

y=x这条直线对应fpr和tpr是相等的,也就是我们模型评估正类和负类的能力是一样的,我们一般认为曲线要在该直线上方才有意义。

三、代码示例

1.ROC曲线

  下面是官方给出的示例,y代表着真实分类,scores代表着y对应的每个样本被预测为正类的概率,也就是说对于第一个样本来说,预测为2的概率为0.1,预测为1的概率为0.9,以此类推。

 roc_curve(y_true,scores,pos_label):对应的参数分别为y的真实标签,预测为正类的概率,pos_label 是指明哪个标签为正类,因为默认都是-1和1,1被当作正类,如果y对应的不是这个,就会报错,所以需要特别指明一下。

返回值为对应的fpr,tpr和thresholds

注意roc_curve只针对二分类情况,多分类情况有点特殊。

roc_curve和auc函数都是用来计算AUC面积的,只不过传入的参数不一样。

from sklearn.metrics import roc_curve  # 返回fpr、tpr、threshhold
from sklearn.metrics import roc_auc_score  # 返回ROC曲线下的面积
from sklearn.metrics import auc  # 返回ROC曲线下的面积
from sklearn.metrics import plot_roc_curve  # 用于绘制ROC曲线
import numpy as np
y = np.array([1, 1, 2, 2])
scores = np.array([0.1, 0.4, 0.35, 0.8])  # 这里的分数代表每个样本被预测为正类的概率
# 返回fpr(假正率)、tpr(真正率)、概率阈值(从大到小排序)
fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2)  # pos_label指定标签2代表正类
print("fpr:", fpr)
print("tpr:", tpr)
print("thresholds:", thresholds)
# 计算AUC面积,二者效果一致
print(roc_auc_score(y, scores))
print(auc(fpr, tpr))
# 输出结果:
fpr: [0.  0.  0.5 0.5 1. ]
tpr: [0.  0.5 0.5 1.  1. ]
thresholds: [1.8  0.8  0.4  0.35 0.1 ]
0.75
0.75

我们可以看到返回的thresholds就对应我们传入的正类概率,但是为什么多了一个1.8呢?我之前也不知道为什么,看了下源码后,是因为我们绘制roc曲线要从(0,0)位置开始,也就是负类样本全部被预测为负类样本,正类样本也全部被预测为负类样本,怎么能够达到这样呢?

首先说一下thresholds是干嘛的,它是一个概率阈值,只有我们的模型预测一个样本的概率达到它,我们才会认为它是正类,一般情况下我们只是认为那个高认为就是哪个类,0.5 和0.5,但是有时候这样是不行的,我们需要更高的阈值进行触发。

这就好解释了,只有达到概率阈值才会认为该样本为正类,我们要是样本都被判为负类,只需要将概率调的非常大,这样很多样本都不会达标。官方的实现是将我们输入的概率值进行排序,取最大的概率+1当作最大的概率。

解释下曲线的几何意义,我们的阈值概率越大,tpr就越小,fpr也越小,随着概率阈值的减小,我们样本被预测为正类的概率变大,那么此时我们的tpr和fpr都会增大,但是之前说过我们的目的是让fpr越小,tpr越大,但是现在我们调整阈值,他们两个都会增大,所有我们就要找到一个临界点,使我们的模型效果最好,也就对应了图片上最好左上角的切线位置,该位置对应的阈值概率是比较好的,能够在较低的假正率的情况下达到较高的真正率。

2.AUC面积

下面用个示例代码解释一下:

# 二分类
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
X, y = load_breast_cancer(return_X_y=True)
clf = LogisticRegression(solver="liblinear", random_state=0).fit(X, y)
print(clf.predict_proba(X))  # 打印预测为1的概率,标签是按字典序进行排序,乳腺癌数据的标签为0、1
y_proba = clf.predict_proba(X)[:, 1]
print(roc_auc_score(y, y_proba))
0.994767718408118

这里有个地方需要x解释一下:

clf.predict_proba(X):它的返回值为模型预测X为每个类别对应的概率,看图中返回的矩阵,我也不知道哪个列对应哪个类别啊,其实它的类别列是按照字典进行排序的,上面我们是乳腺癌数据,标签为0和1,所以第一列就是0分类,第二列就是1分类。

那我们怎么绘制ROC曲线呢?之前已经说过ROC曲线就是有很多的(fpr,tpr)点坐标来的,该坐标是按照不同的概率阈值计算来的,也就是说我们只要获得了fpr和tpr就可以用plt进行画图了,上面的roc_curve()方法可以返回这两个值,然后利用plt.plot()就可以了。

第二种是利用库函数 plot_roc_curve(clf,X,y) ,它的第一个参数是模型,第二个是X,第三个是真实分类,其实内部也是调用模型方法九三出X的预测概率值。

3.绘制曲线

# 绘制ROC曲线的两种方式
import matplotlib.pyplot as plt
# 第一种,计算fpr,tpr
fpr, tpr, thresholds = roc_curve(y, y_proba, pos_label=1)
plt.plot(fpr, tpr, c='r', lw=2, alpha=0.7)
plt.show()
# 第二种,传入模型和数据,内部进行计算
plot_roc_curve(clf, X, y)
plt.show()

4.多分类问题

我们之前所说的ROC曲线以及AUC面积都是针对二分类来说的(正类和负类),那么对于多分类怎么办呢,这些是不是就没用了,也是这些也可以用于多分类情况,我们可以将多分类转化为二分类的问题。

举个例子,现在有四个分类,分别为苹果、香蕉、梨、水蜜桃,我们之前是考虑正类和负类,每一个正类和负类都可以绘制一条ROC曲线,那么针对于多分类怎么办呢?我们这么想,首先对于苹果这个分类来说,我们可以把苹果认为是正类,不是苹果认为负类(也就是所有其它分类都被认为是负类),这样就对应了我们之前的二分类问题,苹果和非苹果,这样就会在图中绘制出一条ROC曲线,但是对于第二种情况就是香蕉了,同理转化为是香蕉和不是香蕉,也可以绘制出一条ROC曲线,这样我们的四分类就可以绘制出4条ROC曲线,最终我们综合4条ROC曲线来拟出一条综合曲线作为最终的ROC曲线,该曲线下的面积也就代表模型预测该4个分类的效果。

加权auc就是可能每个分类的重要程度不一样,所以可以在最终加权的时候利用系数进行控制我们注重的分类效果。

# 多分类问题
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
clf = LogisticRegression(solver="liblinear").fit(X, y)
# 计算多分类的AUC面积
print(roc_auc_score(y, clf.predict_proba(X), average="macro", multi_class="ovr"))

四、数学解释

y = np.array([1, 1, 2, 2]) #正类为2,负类为1
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr: [0.  0.   0.5  0.5  1. ]
tpr: [0.  0.5  0.5  1.   1. ]
thresholds: [1.8  0.8  0.4  0.35 0.1 ]
auc:0.75

我们用数学计算一下上面官方示例的数据,fpr和tpr到底是怎么计算出来的。

我们之前说过要把概率阈值进行从大到小排序,所以得到【1.8,0.8,0.4,0.35,0.1】

1.p=1.8

当p=1.8,也就是所有的样本都被视为负样本,所以此时的混淆矩阵为

image.png


那么此时的fpr和tpr都为0,f p r = 0 / ( 0 + 2 ) = 0 , t p r = 0 / ( 0 + 2 ) = 0 fpr=0/(0+2)=0,tpr=0/(0+2)=0fpr=0/(0+2)=0tpr=0/(0+2)=0

(0,0)

2.p=0.8

当p=0.8时,只有第4个样本别判为正类,其余三个都为负类

image.png


所以此时的f p r = 0 / ( 0 + 2 ) = 0 , t p r = 1 / ( 1 + 1 ) = 0.5 fpr=0/(0+2)=0,tpr=1/(1+1)=0.5fpr=0/(0+2)=0tpr=1/(1+1)=0.5

(0,0.5)

3.p=0.4

当p=0.4时,第二个样本和第四个样本会被认为正类,其余两个没有达到阈值,被视为负类

image.png


所以此时的f p r = 1 / ( 1 + 1 ) = 0.5 , t p r = 1 / ( 1 + 1 ) = 0.5 fpr=1/(1+1)=0.5,tpr=1/(1+1)=0.5fpr=1/(1+1)=0.5tpr=1/(1+1)=0.5

(0.5,0.5)

4.p=0.35

当p=0.4时,第二个样本和和三个、第四个样本会被认为正类,第一个样本没有达到阈值,被视为负类

image.png


所以此时的f p r = 1 / ( 1 + 1 ) = 0.5 , t p r = 2 / ( 2 + 0 ) = 1 fpr=1/(1+1)=0.5,tpr=2/(2+0)=1fpr=1/(1+1)=0.5tpr=2/(2+0)=1

(0.5,1)

5.p=0.1

当p=0.1时,所有样本的概率全部达到阈值,都为预测为正类

image.png


所以此时的f p r = 2 / ( 2 + 0 ) = 1 , t p r = 2 / ( 2 + 0 ) = 1 fpr=2/(2+0)=1,tpr=2/(2+0)=1fpr=2/(2+0)=1tpr=2/(2+0)=1

(1,1)

所以我们可以看到每个概率阈值下计算出来的fpr和tpr组合就是最终返回的fpr和tpr


目录
相关文章
|
1月前
|
机器学习/深度学习 算法 知识图谱
【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)
【机器学习】逻辑回归原理(极大似然估计,逻辑函数Sigmod函数模型详解!!!)
|
1月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
1月前
|
机器学习/深度学习 程序员
【机器学习】朴素贝叶斯原理------迅速了解常见概率的计算
【机器学习】朴素贝叶斯原理------迅速了解常见概率的计算
|
1月前
|
机器学习/深度学习 算法
【机器学习】逻辑回归介绍(逻辑回归应用场景,原理,损失及优化详解!!!)
【机器学习】逻辑回归介绍(逻辑回归应用场景,原理,损失及优化详解!!!)
|
1月前
|
机器学习/深度学习 API
机器学习入门(七):线性回归原理,损失函数和正规方程
机器学习入门(七):线性回归原理,损失函数和正规方程
|
3月前
|
机器学习/深度学习 算法 搜索推荐
【机器学习】机器学习的基本概念、算法的工作原理、实际应用案例
机器学习是人工智能的一个分支,它使计算机能够在没有明确编程的情况下从数据中学习并改进其性能。机器学习的目标是让计算机自动学习模式和规律,从而能够对未知数据做出预测或决策。
96 2
|
2月前
|
机器学习/深度学习 人工智能 算法
探索人工智能:机器学习的基本原理与Python代码实践
【9月更文挑战第6天】本文深入探讨了人工智能领域中的机器学习技术,旨在通过简明的语言和实际的编码示例,为初学者提供一条清晰的学习路径。文章不仅阐述了机器学习的基本概念、主要算法及其应用场景,还通过Python语言展示了如何实现一个简单的线性回归模型。此外,本文还讨论了机器学习面临的挑战和未来发展趋势,以期激发读者对这一前沿技术的兴趣和思考。
|
3月前
|
机器学习/深度学习 人工智能 关系型数据库
【机器学习】Qwen2大模型原理、训练及推理部署实战
【机器学习】Qwen2大模型原理、训练及推理部署实战
664 0
【机器学习】Qwen2大模型原理、训练及推理部署实战
|
3月前
|
机器学习/深度学习 开发者 Python
Python 与 R 在机器学习入门中的学习曲线差异
【8月更文第6天】在机器学习领域,Python 和 R 是两种非常流行的编程语言。Python 以其简洁的语法和广泛的社区支持著称,而 R 则以其强大的统计功能和数据分析能力受到青睐。本文将探讨这两种语言在机器学习入门阶段的学习曲线差异,并通过构建一个简单的线性回归模型来比较它们的体验。
67 7
|
3月前
|
机器学习/深度学习 运维 算法
深入探索机器学习中的支持向量机(SVM)算法:原理、应用与Python代码示例全面解析
【8月更文挑战第6天】在机器学习领域,支持向量机(SVM)犹如璀璨明珠。它是一种强大的监督学习算法,在分类、回归及异常检测中表现出色。SVM通过在高维空间寻找最大间隔超平面来分隔不同类别的数据,提升模型泛化能力。为处理非线性问题,引入了核函数将数据映射到高维空间。SVM在文本分类、图像识别等多个领域有广泛应用,展现出高度灵活性和适应性。
156 2

热门文章

最新文章

下一篇
无影云桌面