评估指标用于反映模型效果。在预测问题中,要评估模型的效果,就需要将模型预测结果f(X)和真实标注Y进行比较,评估指标定义为f(X)和Y的函数。
score = metric(f(X),Y)
模型的好坏是相对的,在对比不同的模型效果时,使用不同评估指标往往会导致不同的结论。
通常,线下使用的是机器学习评估指标,线上使用的是业务指标。如果线下指标和线上指标不同,则可能会出现线下指标变好而线上指标变差的现象,所以我们需要找到和线上业务指标一致的线下指标,尽可能使线下指标的变化趋势跟线上指标一致。没有一个跟线上一致的线下指标,意味着线下指标没有参考价值,想判断此次试验是否有效,只能上线试验。而上线试验成本远高于离线试验成本,通常需要在线试验较长时间并对效果进行可信度检验(如t-test)之后才能得出结论,这必然会导致模型迭代进度变慢。
评估指标根据任务类型分类,可分为分类指标、回归指标、聚类指标和排序指标等。
- 分类指标
常用分类指标有精确率、召回率、F1、AUC与对数损失(Logistic Loss,logloss)。
精确率和召回率多用于二分类问题,需要结合混淆矩阵介绍,如下所示:
其中,TP(真正,True Positive)表示真实结果为正例,预测结果也为正例;FP(假正,False Positive)表示真实结果为负例,预测结果却是正例;TN(真负,True Negative)表示真实结果为负例,预测结果是负例;FN(假负,False Negative)表示真实结果为正例,预测结果是负例。
显然,TP+FP+FN+TN=样本总数。
根据混淆矩阵可以引出如下指标定义:
准确率(Acc):所有的样本中预测正确的比例,计算公式如下:
召回率(Recall)也称查全率、敏感度(Sensitive):所有正样本中预测正确的比例,即正样本的准确率,计算公式如下:
特异性(Specificity):所有负样本中预测正确的比例,即负样本的准确率,计算公式如下:
精确率(Precision)也称查准率:所有预测为正样本的集合中预测正确的比例,计算公式如下:
F1 Score:综合精确率和召回率指标,计算公式如下:
通过F1的计算公式我们可以看出,F1值是介于Precision和Recall之间的。Precision一定情况下反映了模型控制假阳FP个数的能力,Recall值反映了正样本的检出率,F1值综合了两方面。
下面来介绍分类模型特别是二分类模型最重要的评估指标:
ROC与AUC
ROC的全称是“接收者操作特征”(Receiver Operating Characteristic)曲线,是在二战中被发明用于信号检测的,之后很快被引入心理学领域,再后来被引入机器学习领域,用来评估分类、检测结果的指标,如下是一个ROC曲线的图例:
而AUC(Area Under Curve)就是上述ROC曲线下的面积,那么如何计算AUC了,有很多种计算方法,其中绘制ROC曲线是比较通用的方法,首选确定下ROC曲线图的横坐标和纵坐标含义:
横坐标(FPR,即假正率)=1-Specificity=FP/(FP+TN)
纵坐标(TPR,即真正率)=TP/(FP+FN)
但是ROC曲线是由很多个点(FPR,TPR)绘制的曲线,这些点如何计算?
首先对所有样本按预测概率排序,再以每条样本的预测概率值作为判断其他所有样本是正例还是反例的阈值,计算对应的FPR和TPR,然后用线段连接即可。当数据量少时,绘制的ROC曲线不平滑;当数据量大时,绘制的ROC曲线会趋于平滑。
从AUC判断分类器(预测模型)优劣的标准
· AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
· 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值(比如0.5)的话,能有预测价值。
· AUC = 0.5,跟随机猜测一样(例如:抛硬币猜正反面),模型没有预测价值。
· AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
总结:AUC取值越大说明模型越可能将正样本排在负样本前面,另外AUC还有一些统计特性:AUC等于随机挑选一个正样本和负样本时,模型将正样本排前面的概率;AUC和Wilcoxon Test of Ranks等价;AUC还和基尼(Gini)系数有联系,满足等式Gini + 1 = 2 * AUC。
所以AUC是评估二分类模型效果最重要的指标。
对数损失(LogLoss):
若有n个样本,对于第i个样本,它的真实label为yi为{0,1},预测概率为yi’为{0,1},那么LogLoss计算公式如下:
LogLoss衡量的是预测概率分布和真实概率分布的差异性,取值越小越好。与AUC不同,LogLoss对预测概率敏感,
经常作为模型的损失函数来做优化,可是,当训练数据正负样本不平衡时,比如我们经常会遇到正样本很少,负样本很多的情况,我们更希望在控制假正例的情况下检出更多的正样本,若不做任何处理,则降低LogLoss会倾向于偏向负样本一方,此时LogLoss很低,可正样本的检出效果却不理想,反映在模型的效果上就是LogLoss很低,但是模型实际线上效果很差。
参考知乎网上的一个例子:假设有100个样本,其中只有一个正样本,如果模型无脑将所有样本都预测为负样本,如下代码:
from sklearn.metrics import f1_score, roc_auc_score, log_loss
y_true = 99 * [0] + [1]
y_pred = 100 * [0]
print('ROC:', roc_auc_score(y_true, y_pred))
print('LogLoss:', log_loss(y_true, y_pred))
上述代码输出如下:
ROC:0.5
LogLoss:0.34538776394910786
我们可以看到,虽然我们的LogLoss值还不错,但是AUC和随机瞎猜的效果没什么区别。
的情况下检出更多的正样本,若不做任何处理,则降低LogLoss会倾向于偏向负样本一方,此时LogLoss很低,可正样本的检出效果却并不理想。
因为sklearn中的log_loss函数不支持单一类别的计算,比如有时候我就想看看正样本的,然后就报错,所以知乎网友自己写了个log_loss计算函数,代码如下:
import math
def log_loss_custom(y_true, y_pred):
'''
y_true: 真实类别的index列表
y_pred:二维数组,每个样本的预测概率列表
'''
summ = 0.0
for i in range(len(y_true)):
summ -= math.log(max(y_pred[i][y_true[i]], 1e-15))
return summ / len(y_true)
y_true = 10 * [1]
y_pred = 10 * [[0.1, 0.9]]
print('LogLoss:', log_loss_custom(y_true, y_pred))
上述代码的输出如下:
LogLoss: 0.10536051565782631
这个预测效果明显很差的模型,竟然LogLoss值很低。
- 回归指标
平均绝对误差(Mean Absolute Error,MAE):也叫L1范数损失(L1-norm Loss),其公式为:
其中,N为样本数,yi为第i条样本的真实值,pi为第i条样本的预测值。MAE是绝对误差的平均值,因为预测误差有正有负,绝对值可以避免正负抵消。MAE能很好地刻画预测值与真实值的偏差。模型使用MAE作为损失函数则是对数据分布的中值进行拟合。某些模型(如XGBoost)必须要求损失函数有二阶导数,所以不能直接优化MAE。
平均绝对百分误差(Mean Absolute Percentage Error,MAPE):公式如下:
MAPE通过计算绝对误差百分比来表示预测效果,其取值越小越好。如果MAPE=10,这表示预测平均偏离真实值10%。MAPE计算与量纲无关,因此在特定场景下不同问题具有一定可比性。MAPE的缺点也比较明显,在yi=0处无定义,并且如果yi接近0可能导致MAPE大于100%。而且,MAPE对负值误差的惩罚大于正值误差。基于这些缺点也有一些改进的平均指标,如MASE,sMAPE、MDA。
均方根误差(Root Mean Squared Error, RMSE):公式如下:
RMSE代表的是预测值与真实值差值的样本标准差。和MAE相比,RMSE对大误差样本有更大的惩罚;但它对离群点敏感,其健壮性不如MAE。模型使用RMSE作为损失函数则是对数据分布的平均值进行拟合。
基于均方根误差也有一个常用的变种评估指标叫均方根对数误差(Root Mean Squared Logarithmic Error,RMSLE),其公式为:
RMSLE对预测值偏小的样本比对预测值偏大的样本惩罚更大,比如一个酒店消费均价是200元,预测成150元的惩罚会比预测成250元的大。如果评估指标选用RMSLE,没办法直接优化RMSLE但是能直接优化RMSE的模型,通常会先对预测目标进行对数变换ynew=log(y+1),最后预测值再还原p=exppnew-1。
参考资料:
1.https://www.plob.org/article/12476.html
2.https://zhuanlan.zhihu.com/p/87260891