浅谈机器学习的效能衡量指标 (2) -- ROC/AUC 曲线

前言

上一篇谈到準确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1 Score,它们适用在不同的场景,接着我们再来讨论『ROC/AUC 曲线』,它是一个更全面评估效能的指标。

远在1941年『ROC/AUC 曲线』就被用来侦测敌军飞机及船舰,美军利用雷达信号判断飞机、船舰的所在位置,之后也被广泛应用在无线电、生物学、犯罪心理学、医学领域,接下来我们就来领略它的强大威力。

定义

ROC(Receiver operator characteristic):有人翻译为『接收操作特徵图』,其实没甚么帮助,它的定义是在各种『决策门槛』(decision threshold)下,比较『真阳率』(True Positive Rate;TPR)与『假阳率』(False Positive Rate;FPR)间的变化。
http://img2.58codes.com/2024/2000197699R7E8OZaJ.png
图. 『真阳率』与『假阳率』公式

ROC曲线可以绘製成一条曲线,如下图,有多条ROC曲线,相互比较效能,AUC(Area Under the Curve)就比较容易理解,即ROC曲线之下所覆盖的面积,除以总面积的比率。

http://img2.58codes.com/2024/200019767x1FCxnNT4.png
图. ROC曲线比较,X轴为假阳率,Y轴为真阳率。

以雷达侦测为例,信号要大于某个决策门槛(decision threshold),飞机才会出现在雷达萤幕上,假设雷达萤幕旁有一旋钮,可以调整门槛值,如果调高一点,则雷达萤幕侦测敌机的能力变差,有些信号弱的飞机就不会显示,反之,门槛调低一点,则雷达萤幕侦测敌机的能力变强,但是我们可能把天空中的大鸟误认为飞机(假阳率)。因此,可以在各种门槛下计算真阳率及假阳率,作为样本点,将所有样本点连成一线,即ROC曲线,因此,这条线越接近上方,表示真阳率越高,即判断正确的比率越高,换句话说,ROC曲线下方覆盖的面积(AUC)越大,表示效能越好。以上就是ROC/AUC 曲线的精髓。

图解决策门槛对『真阳率』与『假阳率』的影响

我们从二分类的分配(分布)角度来看,如果调整决策门槛,则TP(真阳)、FP(假阳)会随之变化。
http://img2.58codes.com/2024/20001976ciSg6wu8OQ.png
图. TP、TN、FT、FN 的示意图,资料来源:Finding Donors: Classification Project With PySpark

二分类的分配差异越显着,AUC的分数就越高,见下图。
http://img2.58codes.com/2024/20001976fKvLEvonQR.png
图. AUC,资料来源:Finding Donors: Classification Project With PySpark

ROC曲线绘图

接下来我们就要了解如何绘製ROC曲线,範例如下:

资料内容如下,第一栏为预测为真的机率,第二栏为实际值。
http://img2.58codes.com/2024/20001976V5knq1eVDX.png

绘製ROC曲线步骤:

画一个空白图如下。
http://img2.58codes.com/2024/200019766tZhbuv8Ed.png计算第二栏的真(1)与假(0)的个数,假设分别为P及N,Y轴切成P格,X轴切成N格,如下图。
http://img2.58codes.com/2024/20001976OOXZnLWMbC.png以第一栏降幂排序,从大排到小。依序扫描第二栏,若是1,就往『上』画一格,反之,若是0,就往『右』画一格,直到最后一列,如下图。
http://img2.58codes.com/2024/20001976PnV4sdhuMV.png
图. ROC(红线)

绘製原理很直觉,实际值为1(真),表示真阳(预测超过门槛),故Y轴加1格,反之,为假阳(预测超过门槛,但实际为假),故X轴加1格。

程式开发

依照上述步骤,撰写程式如下:

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.metrics import roc_curve, roc_auc_score, auc# 读取资料import pandas as pddf=pd.read_csv('./data.csv')# 计算第二栏的真(1)与假(0)的个数,假设分别为P及NP= df[df['actual']==1].shape[0]N= df[df['actual']==0].shape[0]print(P,N)y_unit=1/PX_unit=1/N# 以第一栏降幂排序,从大排到小。df2=df.sort_values(by='predict', ascending=False)# 依序扫描第二栏,计算每一座标点# 若是1,Y加一单位,反之,若是0,X加一单位X=[]y=[]current_X=0current_y=0for row in df2.itertuples():    # row[0] is index    #print(row[2])    if row[2] == 1:        current_y+=y_unit    else:        current_X+=X_unit    X.append(current_X)    y.append(current_y)X=np.array(X)        y=np.array(y)    print(X, y)# 绘图。   plt.title('Receiver Operating Characteristic')plt.plot(X, y, color = 'orange')plt.legend(loc = 'lower right')plt.plot([0, 1], [0, 1],'r--')plt.xlim([0, 1])plt.ylim([0, 1])plt.ylabel('True Positive Rate')plt.xlabel('False Positive Rate')plt.show()   

直接使用 Scikit-Learn套件更简单,程式如下:

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.metrics import roc_curve, roc_auc_score, auc# 读取资料import pandas as pddf=pd.read_csv('./data.csv')# 在各种『决策门槛』(decision threshold)下,计算 『真阳率』(True Positive Rate;TPR)与『假阳率』(False Positive Rate;FPR)fpr, tpr, threshold = roc_curve(df['actual'], df['predict'])print(fpr, tpr, threshold)auc1 = auc(fpr, tpr)## Plot the resultplt.title('Receiver Operating Characteristic')plt.plot(fpr, tpr, color = 'orange', label = 'AUC = %0.2f' % auc1)plt.legend(loc = 'lower right')plt.plot([0, 1], [0, 1],'r--')plt.xlim([0, 1])plt.ylim([0, 1])plt.ylabel('True Positive Rate')plt.xlabel('False Positive Rate')plt.show()    

执行结果如下:
http://img2.58codes.com/2024/20001976BswTTienj5.png

相关程式码放在这里的 ROC_AUC_sample 目录。

结论

以上说明希望能有助于观念的釐清,如有失当,还请各位先进不吝指正。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章