分类器性能度量指标之ROC曲线、AUC值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分类器性能度量指标之ROC曲线、AUC值相关的知识,希望对你有一定的参考价值。

参考技术A

二分类问题在机器学习中是一个很常见的问题,经常会用到。 ROC (Receiver Operating Characteristic) 曲线和 AUC (Area Under the Curve)(Area Under theCurve) 值常被用来评价一个二值分类器 ( binary classifier ) 的优劣。

对于分类器,或者说分类算法,评价指标主要有precision,recall,F-score等,以及这里要讨论的ROC和AUC。

混淆矩阵是理解大多数评价指标的基础,毫无疑问也是理解AUC的基础。丰富的资料介绍着混淆矩阵的概念,这里用一个经典图来解释混淆矩阵是什么。

显然,混淆矩阵包含四部分的信息:

对照着混淆矩阵,很容易就能把关系、概念理清楚,但是久而久之,也很容易忘记概念。不妨我们按照位置前后分为两部分记忆,前面的部分是True/False表示真假,即代表着预测的正确性,后面的部分是positive/negative表示正负样本,即代表着预测的结果,所以,混淆矩阵即可表示为 正确性-预测结果 的集合。现在我们再来看上述四个部分的概念(均代表样本数,下述省略):

几乎我所知道的所有评价指标,都是建立在混淆矩阵基础上的,包括准确率、精准率、召回率、F1-score,当然也包括AUC。

事实上,要一下子弄清楚什么是AUC并不是那么容易,首先我们要从ROC曲线说起。对于某个 二分类分类器 来说,输出结果标签(0还是1)往往取决于输出的概率以及预定的概率阈值,比如常见的阈值就是0.5,大于0.5的认为是正样本,小于0.5的认为是负样本。如果增大这个阈值,预测错误(针对正样本而言,即指预测是正样本但是预测错误,下同)的概率就会降低但是随之而来的就是预测正确的概率也降低;如果减小这个阈值,那么预测正确的概率会升高但是同时预测错误的概率也会升高。实际上,这种阈值的选取也一定程度上反映了 分类器的分类能力 。我们当然希望无论选取多大的阈值,分类都能尽可能地正确,也就是希望该分类器的分类能力越强越好,一定程度上可以理解成一种鲁棒能力吧。
为了形象地衡量这种分类能力,ROC曲线横空出世!如下图所示,即为一条ROC曲线(该曲线的原始数据第三部分会介绍)。现在关心的是:
- 横轴:False Positive Rate(假阳率,FPR)
- 纵轴:True Positive Rate(真阳率,TPR)

假阳率,简单通俗来理解就是预测为正样本但是预测错了的可能性,显然,我们不希望该指标太高。

真阳率,则是代表预测为正样本但是预测对了的可能性,当然,我们希望真阳率越高越好。

显然, ROC曲线的横纵坐标都在[0,1]之间 ,自然ROC曲线的面积不大于1。现在我们来分析几个特殊情况,从而更好地掌握 ROC曲线的性质

于是,我们可以得到基本的结论: ROC曲线在斜对角线以下,则表示该分类器效果差于随机分类器,反之,效果好于随机分类器,当然,我们希望ROC曲线尽量除于斜对角线以上,也就是向左上角(0,1)凸

ROC曲线一定程度上可以反映分类器的分类效果,但是不够直观,我们希望有这么一个指标,如果这个指标越大越好,越小越差,于是,就有了AUC。AUC实际上就是ROC曲线下的面积。 AUC直观地反映了ROC曲线表达的分类能力

AUC最大的应用应该就是 点击率预估(CTR) 的离线评估。CTR的离线评估在公司的技术流程中占有很重要的地位,一般来说,ABTest和转全观察的资源成本比较大,所以,一个合适的离线评价可以节省很多时间、人力、资源成本。那么, 为什么AUC可以用来评价CTR呢? 我们首先要清楚两个事情:

       1. CTR是把分类器输出的概率当做是点击率的预估值,如业界常用的LR模型,利用sigmoid函数将特征输入与概率输出联系起来,这个输出的概率就是点击率的预估值。内容的召回往往是根据CTR的排序而决定的。
       2. AUC量化了ROC曲线表达的分类能力。这种分类能力是与概率、阈值紧密相关的,分类能力越好(AUC越大),那么输出概率越合理,排序的结果越合理。

我们不仅希望分类器给出是否点击的分类信息,更需要分类器给出准确的概率值,作为排序的依据。所以,这里的 AUC就直观地反映了CTR的准确性 (也就是CTR的排序能力)

[1]From 机器学习和统计里面的auc怎么理解?
[2]From 精确率、召回率、F1 值、ROC、AUC 各自的优缺点是什么?
[3]From 机器学习之分类性能度量指标 : ROC曲线、AUC值、正确率、召回率
[4]From ROC曲线、AUC值

机器学习中的性能指标:精度召回率,PR曲线,ROC曲线和AUC,及示例代码

机器学习中的性能指标:精度、召回率、PR曲线,ROC曲线和AUC

精度、召回率

基本概念

可以通过下图来帮助理解

预测为正/阳性预测为负/阴性指标
真值为正/阳性True Positive(TP)False Negative(FN) R e c a l l = T P T P + F N Recall = \\fracTPTP+FN Recall=TP+FNTP
真值为负/阴性False Positive(FP)True Negative(TN) S p e c i f i c i t y = T N T N + F P Specificity=\\fracTNTN+FP Specificity=TN+FPTN
A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy= \\frac TP +TNTP+TN+FP+FN Accuracy=TP+TN+FP+FNTP+TN P r e c i s i o n = T P ( T P + F P ) Precision=\\fracTP(TP+FP) Precision=(TP+FP)TP F 1 S c o r e = 2 ∗ R e c a l l ∗ P r e c i s i o n R e c a l l + P r e c i s i o n F1 Score=\\frac2*Recall *PrecisionRecall+Precision F1Score=Recall+Precision2RecallPrecision
  • 精度 ( P r e c i s i o n ) (Precision) Precision:预测为阳性样本的准确程度。在信息检索领域也叫查准率。换句话理解:判定为阳性的正确个数除以所有判定为阳性的总素。

  • 召回率 ( R e c a l l ) (Recall) (Recall):也称作敏感度(sensitivity),全部阳性样本中被预测为阳性的比例。在信息检索领域也称作查全率。

    其中精度和召回率同时越高,说明模型性能越好。但精度和召回率在某些情况下是相互矛盾。例如:
    阳性/阴性=50/50,模型只识别出一个为阳性,其余被识别为阴性。此时precision=1/(1+0)=100%, recall=1/(1+49)=2%.

F-Score

通过加权平均综合precision和recall,可以得到F-Score
F S c o r e = ( 1 + a 2 ) ∗ R e c a l l ∗ P r e c i s i o n a 2 ∗ P r e c i s i o n + R e c a l l F Score=\\frac(1+a^2)*Recall *Precisiona^2*Precision+Recall FScore=a2Precision+Recall(1+a2)RecallPrecision
设置 a = 1 a=1 a=1,可以得到F1-Score:
F 1 − s c o r e = 2 ∗ R e c a l l ∗ P r e c i s i o n R e c a l l + P r e c i s i o n F1-score=\\frac2*Recall *PrecisionRecall+Precision F1score=Recall+Precision2RecallPrecision

度量曲线

PR曲线

PR曲线(Precision-Recall Curve):

  • 横轴:召回率;
  • 纵轴:精度。

理想性能是右上角(1,1)处。PR曲线越往右上凸,说明模型性能越好。

PR曲线绘制方法:

  • 根据模型的预测数值,对样本进行从高到低排序,排在前面的样本是正例的可能性更高。
  • 按此顺序逐个样本作为正例进行预测(或设置阈值截断正例和负例),则每次可以计算一个召回率和精度。
  • 将这些值连成(拟合)一条曲线。

使用scikit-learn官方代码示例
使用鸢尾花数据集来绘制PR曲线。

from sklearn.metrics import PrecisionRecallDisplay
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)

# Add noisy features
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.concatenate([X, random_state.randn(n_samples, 200 * n_features)], axis=1)

# Limit to the two first classes, and split into training and test
X_train, X_test, y_train, y_test = train_test_split(
    X[y < 2], y[y < 2], test_size=0.5, random_state=random_state
)
classifier = make_pipeline(StandardScaler(), LinearSVC(random_state=random_state))
classifier.fit(X_train, y_train)
display = PrecisionRecallDisplay.from_estimator(
    classifier, X_test, y_test, name="LinearSVC"
)
_ = display.ax_.set_title("2-class Precision-Recall curve")

ROC曲线

ROC曲线(Receiver-operating-characteristic curve):

  • 横轴:False Positive rate(FPR),度量所有阴性样本中被错误识别为阳性的比率。 F P R = 1 − S p e c i f i c i t y FPR=1-Specificity FPR=1Specificity
    F P R = F P F P + T N FPR =\\fracFPFP+TN FPR=FP+TNFP
  • 纵轴:True positive rate(TPR),即recall。度量所有阳性样本被识别为阳性的比例。

理想性能在左上角(0,1)处。ROC曲线越往左上凸,说明模型性能越好。对角线为随机识别的ROC曲线。绘制方法与PR曲线相似。

PR曲线和ROC曲线的比较

  • ROC曲线:对于各类别之间样本分布比例不敏感,因为FPR和TPR各自只跟真值为负或真值为正的样本相关。
  • PR曲线:对于各类别样本分布比例敏感,因为precision同时和真值正负的样本都相关。

AUC

曲线下方面积(Area under the Curve, AUC):将曲线度量所表达的信息浓缩到一个标量表达。

  • A U C = 1 AUC=1 AUC=1,是完美分类起
  • 0.5 < A U C < 1 0.5<AUC<1 0.5<AUC<1:优于随机猜测。模型妥善设定阈值,能有预测价值
  • A U C = 0.5 AUC=0.5 AUC=0.5:跟随机猜测一样,模型没有预测价值
  • A U C < 0.5 AUC<0.5 AUC<0.5:比随机猜想还差。

使用scikit-learn官方示例代码

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import roc_auc_score

# Import some data to play with
iris = datasets.load_iris()
X = iris.data
y = iris.target

# Binarize the output
y = label_binarize(y, classes=[0, 1, 2])
n_classes = y.shape[1]

# Add noisy features to make the problem harder
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]

# shuffle and split training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

# Learn to predict each class against the other
classifier = OneVsRestClassifier(
    svm.SVC(kernel="linear", probability=True, random_state=random_state)
)
y_score = classifier.fit(X_train, y_train).decision_function(X_test)

# Compute ROC curve and ROC area for each class
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])

# Compute micro-average ROC curve and ROC area
fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel())
roc_auc["micro"] = auc(fpr["micro"], tpr["micro"])

plt.figure(dpi=100)
lw = 2
plt.plot(
    fpr[2],
    tpr[2],
    color="darkorange",
    lw=lw,
    label="ROC curve (area = %0.2f)" % roc_auc[2],
)
plt.plot([0, 1], [0, 1], color="navy", lw=lw, linestyle="--")
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.title("Receiv

以上是关于分类器性能度量指标之ROC曲线、AUC值的主要内容,如果未能解决你的问题,请参考以下文章

人工智能——分类器性能指标之ROC曲线AUC值

人工智能——分类器性能指标之ROC曲线AUC值

分类器性能指标之ROC曲线AUC值

AUC指标之ROC曲线只有一个点的问题

ROC曲线,AUC,和P-R曲线的关系

机器学习中的性能指标:精度召回率,PR曲线,ROC曲线和AUC,及示例代码