auc 是机器学习中二分类问题的常用评价指标,其反映了分类器对正负样本的排序能力。本文介绍一下 auc 指标,然后介绍下 tf.metrics.auc()函数。

性能度量

1 错误率与精度

错误率是分类错误的样本数占样本总数的比例,精度是分类正确的样本数占样本总数的比例。

2 查准率,查全率

对于二分类问题,可以将样例根据其真实类别与学习器预测类别的组合分为真正例,假正例,真反例,假反例,令TP,FP,TN,FN分别表示其对应的样例数,则TP+FP+TN+FN=样例总数。分类结果的混淆矩阵如下表所示:

真实情况 \ 预测结果 正例(预测) 反例(预测)
正例(真实) TP(真正例) FN(假反例)
反例(真实) FP(假正例) TN(真反例)

查准率P与查全率R分别定义为:
$$
P=\frac{TP}{TP+FP}
$$

$$
R=\frac{TP}{TP+FN}
$$

简单来说,查准率就是在预测结果为正例的样本中,真实为正例的占比;查全率就是在真实为正例的样本中,预测结果为正例的占比。查准率和查全率是一对矛盾的度量。

在很多情况下,可以根据学习器的预测结果对样例进行排序,排在前面的是学习器认为最优可能是正例的样本,后面的最不可能为正例。按此顺序逐个将样本作为正例(例如在二分类神经网络中通过调整阈值控制正反例个数),则每次可以计算出当前的查全率,查准率。以查准率为纵轴,查全率为横轴作图,可以得到查准率-查全率曲线,简称“P-R曲线”,显示该曲线的图称为“P-R图”。如下图所示。

P-R曲线下面积越大,则表示该学习器性能越好。关于F1度量貌似不怎么用到,这里就不说了。

3 ROC与AUC

AUC是机器学习中的一个重要二分类指标,其反映了模型对正负样本的排序能力,用通俗的话讲就是,用来评估模型对正负样本的区分能力。

和P-R曲线生成的过程类似,如果将计算查全率,查准率改为计算真正例率TPR,假正例率FPR,并以横轴为假正例率,纵轴为真正例率,可以得到ROC曲线(受试者工作特征),分别定义为:
$$
TPR=\frac{TP}{TP+FN}
$$

$$
FPR=\frac{FP}{TN+FP}
$$

真正例率TPR表示的是在真实为正例的样本中,预测为正例的占比;假正例率FPR表示的是真实为反例的样本中,预测为正例的占比。

显示ROC曲线的图称为ROC图,如下图所示。下图a给出了一个示意图,对角线对应于“随机猜测”模型。点(0,1)对应于将所有正例排在所有反例之前的理想模型。

同P-R图类似,如果ROC曲线下面积越大,则学习器更优。ROC曲线下面积的值也叫AUC(Area Under ROC Curve)。

从定义可知,AUC可通过对ROC曲线下各部分面积求和而得。假定ROC曲线由坐标为${(x_1,y_1), …, (x_m,y_m)}$的点按序连接而成,则AUC可估算为
$$
AUC=\frac{1}{2}\sum_{i=1}^{m-1}{(x_{i+1}-x_i)}\cdot{(y_i+y_{i+1})}
$$
形式化看,AUC考虑的是样本预测的排序质量。

那么如何绘制roc曲线呢?很简单,机器学习一书中已经给了很明确的介绍。

根据有限个点画出roc曲线之后,会发现roc曲线下面积是由一个个小梯形组成。事实上,很多的计算auc的方法都是通过计算小梯形面积之和得到的。选择的分类阈值不同,那么得到auc的值也不同。

TF 实现

在TF1.x 中实现了tf.metrics.auc()函数可以用来计算 AUC。 函数原型如下:

1
2
3
4
5
6
7
8
9
10
def auc(labels,
predictions,
weights=None,
num_thresholds=200,
metrics_collections=None,
updates_collections=None,
curve='ROC',
name=None,
summation_method='trapezoidal',
thresholds=None)

可以看到,只有前两个参数是必须的,其它参数都有默认值。labels 是当前batch训练集的类别集合,predictions表示当前 batch 训练集的输出得分(0-1之前的浮点数)。需要注意的是,num_thresholds参数也是很重要的,它影响了 auc 计算的精度,一般设置num_thresholds<=batch size。

auc 函数的返回值有两个:auc_value, update_op。前者应该是单次 batch 的 auc,后者表示当前batch及之前 batch 的均值。文章《Tensorflow: AUC的错误/问题与修正》也说明了这点,注意看评论。

另外在 TF1.x 中是通过先计算混淆矩阵,然后计算ROC 下面积的一个个小梯形之和得到 AUC 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def compute_auc(tp, fn, tn, fp, name):
"""Computes the roc-auc or pr-auc based on confusion counts."""
if curve == 'PR':
if summation_method == 'trapezoidal':
logging.warning(
'Trapezoidal rule is known to produce incorrect PR-AUCs; '
'please switch to "careful_interpolation" instead.')
elif summation_method == 'careful_interpolation':
# This one is a bit tricky and is handled separately.
return interpolate_pr_auc(tp, fp, fn)
rec = math_ops.div(tp + epsilon, tp + fn + epsilon)
if curve == 'ROC':
fp_rate = math_ops.div(fp, fp + tn + epsilon)
x = fp_rate
y = rec
else: # curve == 'PR'.
prec = math_ops.div(tp + epsilon, tp + fp + epsilon)
x = rec
y = prec
if summation_method in ('trapezoidal', 'careful_interpolation'):
# 一般传入的参数默认是trapezoidal
return math_ops.reduce_sum(
math_ops.multiply(x[:num_thresholds - 1] - x[1:],
(y[:num_thresholds - 1] + y[1:]) / 2.),
name=name)

参考文献

周志华 机器学习。