评估分类模型

分类模型相对是比较好评估的,一般来说我们在训练时会将训练数据分为训练集,验证集和测试集三份或者训练集,测试集两份.当模型训练完成,基于模型在测试集上的预测结果和真实结果,计算一些指标来评估模型的泛化能力.这些指标主要包括准确度(accuracy),精确度(precision),召回率(recall),F1,AUC.理论上来看,指标越大,模型的泛化能力越强.
这些指标按照内在逻辑可以分为两种

  1. 基于样例的.这类指标基于测试集每个样例的预测结果和真实结果,每个样例的对比结果是独立的.包括准确度,精确度,召回率和F1
  2. 基于排序的.考虑到大多数分类模型的输出是属于各个类的概率分布,比如线性回归和逻辑回归.我们可以对比测试集整体按照概率排序的预测结果和真实情况来作为对模型的评价.比如AUC

基于样例的指标

在介绍指标之前,不妨假设这是二分类问题,类别有正/负两种(或者1/0两种),先给出以下四种定义,用来划分测试集:

  • 预测为正且实际为正的 叫做TP(True Positive).
  • 预测为正且实际为负的 叫做FP(False Positive).
  • 预测为负且实际为正的 叫做FN(False Negative).
  • 预测为负且实际为负的 叫做TN(True Negative).

测试集中的样本一定会符合以上四种定义之一.

横轴预测,纵轴真值 预测为正 预测为负 不论预测
实际为正 TP FN P
实际为负 FP TN N

如果没有特殊说明,这六种符号均表示符合对应定义的样本的数量.

准确度(accuracy)

准确度反映的是预测值与真值一致的程度.其分子为预测对的样本的数量,分母为测试集总的样本数量.

$$ Accurcy =\frac{TP + TN}{TP + FP + TN + FN} $$

精确度(precision)

$$ precision = \frac {TP}{TP+FP}$$

准确度是预测为正的样本中真值为正的百分比.

召回率(recall)

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

召回率描述的是真值为正的样本中被预测为正的比例.也叫TPR(True Positive Rate).

F1_score

我们不妨想象,一个分类器把所有样本都预测为正,则召回率很高;如果它只把样本中最有可能为正的一个预测为正,其他都为负,则准确度很高.所以精确度和召回率都不能独自完全描述一个模型的准确程度.而F1是准确度和召回率的调和平均,是综合准确度和召回率的一种指标.

$$ F1 = \frac{1}{\frac{\frac{1}{precision} + \frac{1}{recall}}{2}} = 2 * \frac {precision * recall}{precision + recall} $$

混淆矩阵(confusion matrix)

混淆矩阵是更加细致的一个模型效果评估工具,它的纵轴为真实标签,横轴为预测标签,其中的数字则是命中的个数.通过这个可以比较清晰地看出模型预测的偏向性,以此可以作为模型调整的依据.

比如我们有如下的混淆矩阵,就可以看出把真值非1的样本预测为1的比率很高,背后原因可能是因为训练集中1类的样本很多.

横轴预测,纵轴真值 预测为1 预测为2 预测为3
实际为1 5 2 0
实际为2 5 3 0
实际为3 10 0 2

基于排序的指标

AUC(Area Under Curve)

除了precision, recall, F1等基于样例的评价指标,还有AUC(Area Under Curve)这种关于样本总体顺序的指标.
AUC是ROC曲线和y=0直线和x=1直线围的面积,换句话说就是ROC曲线下的面积.

ROC(Receiver Operating Characteristic curve)

ROC是输出概率分布的二分类器分类能力的一种图形化展示,通过改变阈值(为正的概率大于0.5则预测为正,否则为负,这里0.5就是阈值)画出召回率相对错误正类率的图像.
实际操作中就是

  1. 我们从所有样例的预测概率和比最小概率略小的数组成的集合中取阈值,
  2. 计算该阈值下的召回率和错误正类率作为y坐标和x坐标画在二维空间上,
    • 当阈值取0时,所有样例都被预测为正,则召回率为1,FPR也为1.
    • 当阈值取最大值时,所有样例都被预测为负,则召回率为0,FPR也是0.
    • 阈值越小时,样例被错误地预测为正的风险越大,也就是FPR越接近1,召回真值为正的样例越容易,也就是召回率越接近1.
  3. 将这些点连起来.连成的这条曲线就是ROC曲线(折线).

错误正类率(False Positive Rate, FPR)

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

FPR反映的是真值为负的样例中有多少被错误地预测为正的.

理解AUC为什么反映的是样本的总体排序

为什么说ROC反映的是样本中样例顺序呢?因为ROC的每个点对应一个阈值,而这个阈值对应了按照预测概率升序排序后样本的一种分类方式(排名第几之后的样例全部预测为正). ROC的绘制可以描述为

  1. 按照预测概率升序排序后样本从后往前遍历(程序员可以想象有个指针),每遇到一个真值为负的样例(称为负样例),
  2. 把该样例前一个样例的概率(或者该样例的概率和前一个样例的概率之间的某个实数作为阈值,实数稠密性保证阈值必定存在)作为阈值,也就是说该负样例和之后的样例预测为正,之前的为负.这时我们在ROC上绘制一个点.
  3. 直到最后一个负样例 这样绘制的点是从左往右的,直到(1,1)点.

为什么说AUC可以体现样本中样例顺序呢?因为按照预测概率升序排序后样本

我们不妨想象

  • 理想的二分类模型是所有正样例排在所有负样例之后.从后往前遍历,我们遇到第一个负样例后才会有FPR大于0,而召回率一直都是1.那么ROC就是连接(0, 0),($\frac{1}{负样例的个数}$, 1)和(1,1)三点的折线.AUC就很接近1.当负样例数量无限大时,AUC就是1.
  • 最糟糕的二分类器就是所有负样例排在所有正样例之后,ROC曲线就是连接(0,0),($1 - \frac{1}{负样例个数}$,0)和(1,1)的折线.当负样例数量无限大时,AUC就是0.
  • 第一个负样例出现的位置越靠后,召回率越低,这个点(ROC曲线从左往右第一个点)下面的面积就越小(积分上讲,其实是该点附近折线下的面积).同样,第二个负样例出现的位置越靠后,召回率越低,ROC曲线第二个点下面的面积越小.推而广之,负样例出现在正样例之前的情况越多,ROC曲线覆盖的面积越小,也就是AUC越小.

使用sklearn做模型评估

除了上面的这些指标,sklearn还提供了一些其他接口来做分类模型的评估

接口 说明
metrics.accuracy_score(y_true, y_pred[, …]) 模型准确度(Accuracy)
metrics.auc(x, y[, reorder]) 使用梯形法则计算曲线下面积(AUC)
metrics.average_precision_score(y_true, y_score) 计算平均精确率(AP)
metrics.brier_score_loss(y_true, y_prob[, …]) 计算Brier得分
metrics.classification_report(y_true, y_pred) 构建主要分类指标的文本报告
metrics.cohen_kappa_score(y1, y2[, labels, …]) Cohen's kappa: 一个衡量内部注释者协议的统计量
metrics.confusion_matrix(y_true, y_pred[, …]) 计算混淆矩阵来评估分类的准确性
metrics.f1_score(y_true, y_pred[, labels, …]) 计算F1得分
metrics.fbeta_score(y_true, y_pred, beta[, …]) 计算F-beta得分
metrics.hamming_loss(y_true, y_pred[, …]) 计算平均海明损失
metrics.hinge_loss(y_true, pred_decision[, …]) 计算平均hinge损失
metrics.jaccard_similarity_score(y_true, y_pred) Jaccard相似系数评分
metrics.log_loss(y_true, y_pred[, eps, …]) 对数损失,又名逻辑损失或交叉熵损失
metrics.matthews_corrcoef(y_true, y_pred[, …]) 计算马修斯相关系数(MCC)
metrics.precision_recall_curve(y_true, …) 针对不同的概率阈值计算精度(precision),召回率对
metrics.precision_recall_fscore_support(…) 计算精度,召回率,f1,support对
metrics.precision_score(y_true, y_pred[, …]) 计算精度
metrics.recall_score(y_true, y_pred[, …]) 计算召回
metrics.roc_auc_score(y_true, y_score[, …]) 计算特征曲线(ROC AUC)下预测分数的计算区域
metrics.roc_curve(y_true, y_score[, …]) 计算ROC
metrics.zero_one_loss(y_true, y_pred[, …]) 0-1分类器损失

指标的选取

使用哪种或哪些指标来评估模型时,需要考虑模型的应用.

  • 如果我们更关注模型对单个样例的预测,比如预测一个用户的性别而不关心两个用户之间相对的性别倾向时,基于样例的指标就更合适;
  • 如果我们侧重的是不同样例的对比关系或者整个样本(全部样例)的顺序,比如做推荐时做点击率预测,我们更加侧重不同物品被点击的相对大小,这个时候基于排序的指标就更有意义.