参考资料
- 《百面机器学习》
- https://blog.csdn.net/hfutdog/article/details/88085878
准确率(Accuracy)
定义
指分类正确的样本占总样本个数的比例,即
A c c u r a c y = n c o r r e c t n t o t a l = T P + T N T P + T N + F P + F N Accuracy=\frac{n_{correct}}{n_{total}}=\frac{TP+TN}{TP+TN+FP+FN} Accuracy=ntotalncorrect=TP+TN+FP+FNTP+TN
局限性
当不同类别的样本比例非常不均衡时,占比大的类别往往成为影响准确率的最主要因素。可以使用平均准确率(每个类别下的样本准确率的算术平均)作为模型评估的指标。
代码示例
from sklearn.metrics import accuracy_score
y_pred = [0, 2, 1, 3]
y_true = [0, 1, 2, 3]
print(accuracy_score(y_true, y_pred))
精确率(Precision)与召回率(Recall)
定义
精确率(精度):指分类正确的正样本个数占分类器判定为正样本的样本个数的比例。
P r e c i s i o n = T P T P + F P Precision=\frac{TP}{TP+FP} Precision=TP+FPTP
召回率:指分类正确的样本占真正的正样本个数的比例。
R e c a l l = T P T P + F N Recall=\frac{TP}{TP+FN} Recall=TP+FNTP
二者联系
精确率和召回率是既矛盾又统一的两个指标,为了提高精确率,分类器需要尽量在“更有把握”时才把样本预测为正样本,但此时往往漏掉许多“没有把握”的正样本,导致召回率降低。
为了综合评估一个排序模型的好坏,最好计算出F1分数或绘制出模型的P-R(Precision-Recall)曲线。
F1分数(F1 score)
是精确率和召回率的调和平均值。定义为:
F 1 = 2 × p r e c i s i o n × r e c a l l p r e c i s i o n + r e c a l l F1=\frac{2\times precision\times recall}{precision+recall} F1=precision+recall2×precision×recall
P-R曲线
横坐标是召回率,纵坐标是精确率。整条P-R曲线通过将阈值从高到低移动而成的,原点附近代表当阈值最大时模型的精确率和召回率。
代码示例
precision、recall和F1
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
y_pred = [0, 0, 1, 1]
y_true = [0, 1, 0, 1]
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1_score(y_true, y_pred)
注:precision_score()、recall_score()和f1_score()都有一个参数average。可选值为[None, ‘binary’(默认), ‘micro’, ‘macro’, ‘samples’, ‘weighted’]。多类或者多标签目标需要这个参数:
-
‘None’:每个类别的分数将会返回;
-
‘binary’:仅报告由pos_label(即正例标签,默认为1)指定的类的结果. 这仅适用于目标是二进制的情况;
-
‘micro’:通过计算总的真阳性、假阴性和假阳性来全局计算指标。换句话说,微平均是指计算多分类指标时赋予所有类别的每个样本相同的权重,将所有样本合在一起计算各个指标。
-
‘macro’:为每个标签计算指标,找到它们未加权的均值,它不考虑标签数量不平衡的情况。换句话说,宏平均是指在计算均值时使每个类别具有相同的权重,最后结果是每个类别的指标的算术平均值;
-
‘weighted’:为每个标签计算指标,并通过各类占比找到它们的加权均值(每个标签的正例数)。
总结:
-
如果每个类别的样本数量差不多,那么宏平均和微平均没有太大差异;
-
如果每个类别的样本数量差异很大,那么注重样本量多的类时使用微平均,注重样本量少的类时使用宏平均;
-
如果微平均大大低于宏平均,那么检查样本量多的类来确定指标表现差的原因;
-
如果宏平均大大低于微平均,那么检查样本量少的类来确定指标表现差的原因。
P-R曲线
import numpy as np
from sklearn.metrics import precision_recall_curve
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
precision, recall, thresholds = precision_recall_curve(
y_true, y_scores)
需要注意的是,precision_recall_curve()的输入是真实标签和预测分数,而不是真实标签和预测标签,因为P-R需要调整阈值,返回当前的precision和recall。
平方根误差(RMSE)
定义
RMSE经常用来衡量回归模型的好坏。公式为
R M S E = ∑ i = 1 n ( y i − y ^ i ) 2 n RMSE=\sqrt{\frac{\sum_{i=1}^{n}\left ( y_{i}-\hat{y}_{i}\right )^{2}}{n}} RMSE=n∑i=1n(yi−y^i)2
局限性
如果存在个别偏离程度非常大的离群点时,即使离群点非常少,也会让RMSE指标变得很差。可以从三个角度考虑:
-
如果这些离群点是“噪声点”,需要在数据预处理阶段过滤掉;
-
如果不是“噪声点”,需要进一步提高模型的预测能力,将离群点产生的机制建模进去;
-
使用更鲁棒的指标,如平均绝对百分比误差(Mean Absolute Percent Error, MAPE):
M A P E = ∑ i = 1 n ∣ y i − y ^ i y i ∣ × 100 n MAPE=\sum_{i=1}^{n}\left | \frac{y_{i}-\hat{y}_{i}}{y_{i}}\right |\times \frac{100}{n} MAPE=∑i=1n∣∣∣yiyi−y^i∣∣∣×n100
其将每个误差点进行了归一化,降低了个别离群点带来的绝对误差的影响。
ROC曲线(Receiver Operating Characteristic Curve)
定义
ROC曲线经常作为评估二值分类器最重要的指标之一,其横坐标为假阳性率(FPR),纵坐标为真阳性率(TPR),计算公式如下:
F P R = F P N FPR=\frac{FP}{N} FPR=NFP
T P R = T P P TPR=\frac{TP}{P} TPR=PTP
绘制ROC曲线
在二值分类问题中,模型的输出一般都是预测样本为正例的概率。样本按照预测概率从高到低排序,指定一个阈值,预测概率大于该阈值的样本会被判为正例,否则为负例。通过动态地调整阈值,从最高的得分开始(从正无穷开始),逐渐调整到最低得分,每一个阈值对应一个FPR和TPR。
另一种方式:首先,根据统计出正负样本的数量P和N;接下来,把横坐标的刻度间隔设置为 1 / N 1/N 1/N,纵坐标的刻度间隔设置为 1 / P 1/P 1/P;再根据模型输出的预测概率对样本从高到低排序;依次遍历样本,同时从零开始绘制ROC曲线,每遇到一个正样本就沿着纵坐标绘制一个刻度间隔的曲线,每遇到一个负样本就沿着横坐标方向绘制一个刻度间隔的曲线,直到遍历完所有样本。
AUC(Area Under Curve)
指ROC曲线下的面积大小,反映基于ROC曲线衡量出的模型性能。AUC越大,说明分类器性能越好。
代码示例
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y_true, y_scores)
auc_value = auc(fpr, tpr)
ROC v.s. P-R
相比P-R曲线,ROC曲线有一个特点,当正负样本的分布发生变化时,ROC曲线的形状能够基本保持不变,而P-R曲线的形状一般会发生较剧烈的变化。即ROC曲线能够尽量降低不同测试集带来的干扰,更加客观、稳定地衡量模型本身的性能。如果希望更多地看到模型在特定数据集上的表现,P-R曲线则能够更直观地反映其性能。