【理论 | 代码】机器学习分类与回归性能评估指标大全

一、回归指标

1.1 均方误差(Mean Squared Error, MSE)

MSE 称为均方误差,又被称为 L2 范数损失,该统计参数是预测数据和原始数据对应点误差的平方和的均值,公式如下:
M S E = 1 n ∑ i = 1 n w i ( y i − y i ^ ) 2 = S S E n MSE = \frac{1}{n}\sum_{i=1}^nw_i(y_i - \hat{y_i})^2 = \frac{SSE}{n} MSE=n1i=1nwi(yiyi^)2=nSSE

w i w_i wi 为每个样本数据的权重系数, w i w_i wi > 0, 通常为 1

范围 [0, ∞ \infty ],当预测值与真实值完全吻合时等于0,即完美模型;误差越大,该值越大。总而言之,值越小,机器学习网络模型越精确,相反,则越差。

优点:

  • MSE会得到一个只有一个全局最小值的梯度下降。
  • 对于小的误差,它可以有效地收敛到最小值,没有局部最小值。
  • MSE 通过对模型进行平方来惩罚具有巨大错误的模型

缺点:

  • 对异常值的敏感性通过对它们进行平方来放大高误差。
  • MSE 会受到异常值的影响,会寻找在整体水平上表现足够好的模型。
from sklearn.metrics import mean_squared_error
import numpy as np
# 第一种写法
MSE = mean_squared_error(y_true, y_pred) # mean_squared_error(真实样本标签,预测值)

# 或者自定义
MSE = np.mean(np.square(y_true - y_pred))

# 或者
MSE = np.sum((y_true - y_pred) ** 2) / len(y_true)

# 或者 MSE--相当于y_true - y_pred的二阶范数的平方/n
MSE = np.linalg.norm(y_true - y_pred, ord=2)**2/len(y_true)

(1)Normalized Root Mean Squared Error (NRMSE)

归一化 RMSE 通常通过除以一个标量值来计算,它可以有不同的方式。有时选择四分位数范围可能是最好的选择,因为其他方法容易出现异常值。当想要比较不同因变量的模型或修改因变量时,NRMSE 是一个很好的度量。它克服了尺度依赖性,简化了不同尺度模型甚至数据集之间的比较。

import numpy as np

def normalized_root_mean_squared_error(y_true, y_pred):  
    squared_error = np.square((y_true- y_pred))  
    sum_squared_error = np.sum(squared_error)  
    rmse = np.sqrt(sum_squared_error / len(y_true))  
    nrmse_loss = rmse/np.std(y_pred)  
    return nrmse_loss  

(2)Relative Root Mean Squared Error (RRMSE)

RRMSE 是 RMSE 的无量纲形式,是由均方根值归一化的均方根误差,其中每个残差都根据实际值进行缩放

def relative_root_mean_squared_error(y_true, y_pred):  
    num = np.sum(np.square(y_true - y_pred))  
    den = np.sum(np.square(y_pred))  
    squared_error = num/den  
    rrmse_loss = np.sqrt(squared_error)  
    return rrmse_loss  

(3)Root Mean Squared Logarithmic Error (RMSLE)

均方根对数误差是通过将 log 应用于实际值和预测值然后取它们的差异来计算的。RMSLE 对于小误差和大误差被均匀处理的异常值是稳健的。如果预测值小于实际值,则对模型进行更多的惩罚,而如果预测值大于实际值,则对模型进行较少的惩罚。

优点:

  • 不依赖于比例,并且适用于各种比例。
  • 它不受大异常值的影响。
  • 它只考虑实际值和预测值之间的相对误差。
def root_mean_squared_log_error(y_true, y_pred):  
    square_error = np.square((np.log(y_true + 1) - np.log(y_pred + 1)))  
    mean_square_log_error = np.mean(square_error)  
    rmsle_loss = np.sqrt(mean_square_log_error)  
    return rmsle_loss  

1.2 均方根误差 (Root Mean Squard Error, RMSE)

MSE 开根号后就成了 RMSE,RMSE 值为零表示模型完美拟合。RMSE 越低,模型及其预测就越好。公式如下:
R M S E = M S E = S S E / n = 1 n ∑ i = 1 n w i ( y i − y i ^ ) 2 RMSE = \sqrt{MSE} = \sqrt{SSE/n} = \sqrt{\frac{1}{n}\sum_{i=1}^nw_i(y_i - \hat{y_i})^2} RMSE=MSE =SSE/n =n1i=1nwi(yiyi^)2

为什么要开根号呢?有意义么?其实实质是一样的。只不过用于数据更好的描述。

例如:要做房价预测,每平方是万元,预测结果也是万元。那么差值的平方单位即是千万级别的。那就不太好描述自己做的模型效果。于是开根号后,误差结果的量纲就跟原始数据的是一个级别了,更便于描述我们预测的结果。

优点:

  • 易于理解,计算方便

缺点:

  • 建议去除异常值才能使其正常运行。
  • 会受到数据样本大小的影响。
  • 它是使用平均误差,而平均值对异常点(outliers)较敏感,如果回归器对某个点的回归值很不理性,那么它的误差则较大,从而会对RMSE的值有较大影响,即平均值是非鲁棒的。
from math import sqrt
from sklearn.metrics import mean_squared_error

# 第一种方式
rmse = sqrt(mean_squared_error(y_true, y_pred)

# 或者 RMSE--相当于y-y_hat的二阶范数/根号n
RMSE = np.linalg.norm(y-y_hat, ord=2)/len(y)**0.5

# 或者
RMSE = np.sqrt(np.mean(np.square(y - y_hat)))

1.3 平均绝对误差 (Mean Absolute Error,MAE)

MAE是预测值与观测值之间的绝对差值的平均值,又被称为 L1范数损失,仅测量误差的大小,不关心它们的方向,MAE越低,模型的准确性就越高。公式如下:
M A E = 1 n ∑ i = 1 n ∣ w i ( y i − y i ^ ) ∣ MAE = \frac{1}{n}\sum_{i=1}^n|w_i(y_i - \hat{y_i})| MAE=n1i=1nwi(yiyi^)

RMSE(MSE)和MAE都是最常用的回归评价指标,如何选择呢?

MAE直接取平均偏移,而RMSE比MAE惩罚更高的差异。比如:

案例 1:实际值= [2,4,6,8],预测值= [4,6,8,10]
案例 2:实际值= [2,4,6,8],预测值= [4,6,8,12]

这时,

案例 1 的MAE = 2.0,案例 1 的RMSE = 2.0
案例 2 的MAE = 2.5,案例 2 的RMSE = 2.65

从上面的例子中,可以看到,对于预测较差的值,RMSE 比 MAE 给与更高的惩罚。通常,RMSE 将高于或等于 MAE。它等于 MAE 的情况是当所有差异相等或为零时。

然而,RMSE 是许多模型的默认评价指标,因为根据 RMSE 定义,其是平滑可微的,从而使得更容易执行数学运算,例如求梯度。

还有一个重要的区别是,最小化一组数字上的平方误差 RMSE 会导致找到它的均值,并且最小化平均绝对误差MAE会导致找到它的中位数。这就是为什么MAE对异常值具有鲁棒性而RMSE不强的原因。

总结一下,RMSE 与 MAE 的主要区别是:

  • ① RMSE 比 MAE 惩罚更高的差异
  • ② RMSE 是平滑可微的
  • ③ MAE 对异常值更鲁棒

优点:

  • 由于采用了绝对值,因此所有误差都以相同的比例加权。
  • 如果训练数据有异常值,MAE 不会惩罚由异常值引起的高错误。
  • 它提供了模型执行情况的平均度量。

缺点:

  • 有时来自异常值的大错误最终被视为与低错误相同。
  • 在零处不可微分。许多优化算法倾向于使用微分来找到评估指标中参数的最佳值。在 MAE 中计算梯度可能具有挑战性。
from sklearn.metrics import mean_absolute_error
MAE = mean_absolute_error(y_true, y_pred)

# 或者 MAE--相当于y-y_hat的一阶范数/n
MAE = np.linalg.norm(y-y_hat, ord=1)/len(y)

# 或者
MAE = np.mean(np.abs(y-y_hat))

1.4 R Squared (R 2 ^2 2) 和校正 R 2 ^2 2

决定系数是相关系数的平方。 相关系数是用来描述两个变量之间的线性关系的,但决定系数的适用范围更广,可以用于描述非线性或者有两个及两个以上自变量的相关关系。

1.4.1 R Squared (R 2 ^2 2)

决定系数(coefficient ofdetermination),也称为拟合优度, 反应了 y y y 的波动有多少百分比能被 x x x 的波动所描述,即表征依变数 Y Y Y 的变异中有多少百分比,可由控制的自变数 X X X 来解释.

R 2 ^2 2 是 0 说明因变量的结果是一个常数(无效果)。如果结果是 1,说明预测出来的就是原本函数。如果是 0-1 之间的,就是代表模型的好坏,越大越好,如果结果为负数,还不如不训练来得好。

这就是我们要介绍的 R 2 ^2 2,它是一个无量纲化的指标。公式如下:
R 2 = S S R / S S T = 1 − S S E / S S T = 1 − ∑ i = 1 n ( y i − y i ^ ) 2 ∑ i = 1 n ( y i − y i ˉ ) 2 = 1 − M S E 1 n ∑ i = 1 n ( y i − y i ˉ ) 2 R2=SSR/SST=1-SSE/SST = 1 - \frac{\sum_{i=1}^n(y_i - \hat{y_i})^2}{\sum_{i=1}^n(y_i - \bar{y_i})^2} = 1 - \frac{MSE}{\frac{1}{n}\sum_{i=1}^n(y_i - \bar{y_i})^2} R2=SSR/SST=1SSE/SST=1i=1n(yiyiˉ)2i=1n(yiyi^)2=1n1i=1n(yiyiˉ)2MSE

其中:SST = SSR + SSE

  • SST (total sum of squares):总平方和
  • SSR (regression sum of squares):回归平方和
  • SSE (error sum of squares) :残差平方和。

分子就是 MSE。分母就是标签 y y y 的方差。

缺点:

  • 均值对异常点(outliers)较敏感,如果样本中有一些异常值出现,会对以上指标的值有较大影响,即均值是非鲁棒的。

优点:

  • 不同模型不同情景下,定义统一的规则来衡量模型的好坏,即均在[0,1]之间
from sklearn.metrics import r2_score
r2 = r2_score(y_true, y_pred) # r2_score(真实样本标签,预测值)

1.4.2 校正 R 2 R^2 R2(Adjusted R-square)

R 2 R^2 R2 用来评价模型的拟合程度。当在评价拟合程度的同时,也考虑到模型的复杂程度,那么校正 R 2 R^2 R2(Adjusted R-square)就被提出来,Adjusted R-Square 抵消样本数量对 R-Square 的影响,做到了真正的 0~1,越大越好。。

校正 R 2 R^2 R2 是考虑到了自由度下的 R 2 R^2 R2 .
R 2 = 1 − S S R e s S S T o t a l R^2 = 1 - \frac{SS_{Res}}{SS_{Total}} R2=1SSTotalSSRes

考虑到残差平方和 S S R e s SS_{Res} SSRes 的自由度为 n − p − 1 n-p-1 np1, 总体平方和 S S T o t a l SS_{Total} SSTotal 的自由度为 n − 1 n-1 n1,那么校正后的 R 2 _ adjusted R^2\_\text{adjusted} R2_adjusted 的公式为:
R 2 _ adjusted = 1 − S S R e s / ( n − p − 1 ) S S T o t a l / ( n − 1 ) = 1 − S S R e s S S T o t a l n − 1 n − p − 1 = 1 − ( 1 − R 2 ) ( n − 1 ) n − p − 1 R^2\_\text{adjusted} = 1 - \frac{SS_{Res}/(n-p-1)}{SS_{Total}/(n-1)} = 1 - \frac{SS_{Res}}{SS_{Total}} \frac{n-1}{n-p-1} = 1 - (1 - R^2)\frac{(n-1)}{n -p - 1} R2_adjusted=1SSTotal/(n1)SSRes/(np1)=1SSTotalSSResnp1n1=1(1R2)np1(n1)

公式中的 n n n 是样本的个数, p p p 是变量的个数。


那么对于 R 2 R^2 R2 和校正 R 2 R^2 R2,应该如何选择呢?

在前面也已经提到了,校正 R 2 R^2 R2 考虑到了模型的复杂程度。下面举例来说明:

def ad_r2(true, pred, fea_nums=3):
  
    SS_Residual = sum((true-pred)**2)
    SS_Total = sum((true-np.mean(true))**2)
    r_squared = 1 - (float(SS_Residual))/SS_Total
    adj_r_squared = 1 - (1-r_squared)*(len(true)-1)/(len(true)-3-1)
    return adj_r_squared

1.5 相对平方误差(Relative Squared Error,RSE)

相对平方误差需要使用均方误差并将其除以实际数据与数据平均值之间的差异的平方。

优点

  • 对预测的平均值和规模不敏感。
def relative_squared_error(true, pred):  
    true_mean = np.mean(true)  
    squared_error_num = np.sum(np.square(true - pred))  
    squared_error_den = np.sum(np.square(true - true_mean))  
    rse_loss = squared_error_num / squared_error_den  
    return rse_loss  

1.6 平均偏差误差(Mean Bias Error,MBE)

平均偏差误差是测量过程高估或低估参数值的趋势。偏差只有一个方向,可以是正的,也可以是负的。正偏差意味着数据的误差被高估,负偏差意味着误差被低估。平均偏差误差是预测值与实际值之差的平均值。该评估指标量化了总体偏差并捕获了预测中的平均偏差。它几乎与 MAE 相似,唯一的区别是这里没有取绝对值。这个评估指标应该小心处理,因为正负误差可以相互抵消。

优点:

  • 想检查模型的方向(即是否存在正偏差或负偏差)并纠正模型偏差,MBE 是一个很好的衡量标准。

缺点:

  • 就幅度而言,这不是一个好的衡量标准,因为误差往往会相互补偿。
  • 它的可靠性不高,因为有时高个体错误会产生低MBE。
  • 作为一种评估指标,它在一个方向上可能始终是错误的。
def mean_bias_error(true, pred):  
    bias_error = true - pred  
    mbe_loss = np.mean(np.sum(diff) / true.size)  
    return mbe_loss  

1.7 相对绝对误差(Relative Absolute Error,RAE)

相对绝对误差是通过将总绝对误差除以平均值和实际值之间的绝对差来计算的。RAE 并以比率表示。RAE 的值从0到1。一个好的模型将具有接近于零的值,其中零是最佳值。

优点:

  • RAE 可用于比较以不同单位测量误差的模型。
  • RAE 是可靠的,因为它可以防止异常值
def relative_absolute_error(true, pred):  
    true_mean = np.mean(true)  
    squared_error_num = np.sum(np.abs(true - pred))  
    squared_error_den = np.sum(np.abs(true - true_mean))  
    rae_loss = squared_error_num / squared_error_den  
    return rae_loss  

1.8 均方百分比误差 MSPE

考虑以下问题。目标是预测两家商店将销售多少台笔记本电脑?

商店 1:预测 9,售出 10,MSE = 1
商店 2:预测 999,售出 1000,MSE = 1

或者,

商店 1:预测 9,售出 10,MSE = 1
商店 2:预测 900,售出 1000,MSE = 10000

对于前面这种情况,MSE是相同的,我们难以确定谁好谁坏。对于后面这种情况,尽管商店2的MSE非常大,但是900也是很不错了。在这种情况下,我们难以确定谁好谁坏。

这基本上是因为MSE使用绝对平方误差,而相对误差对我们来说更重要。

相对误差偏好可以用均方百分比误差MSPE(Mean Square Percentage Error)表示。对于每个样本,绝对误差除以目标值,给出相对误差。MSPE公式如下:
M S P E = 100 N ∑ i = 1 N ( y i − y i ^ y i ) 2 MSPE = \frac{100}{N} \sum_{i=1}^N (\frac{y_i - \hat{y_i}}{y_i})^2 MSPE=N100i=1N(yiyiyi^)2

因此,MSPE 可以被认为是 MSE 的加权版本。其样本的权重与其真实的目标平方成反比。

import numpy as np
# 均方百分比误差 MSPE
def MSPE(true, pred):
    true = true + 0.1  # 避免0值
    diff = np.array(true) - np.array(pred)
    return np.mean(np.power(diff / true, 2))

1.9 平均绝对百分比误差 MAPE

相对误差偏好也可以用平均绝对百分比误差 MAPE(Mean Absolute Percentage Error)表示。对于每个样本,绝对误差除以目标值,给出相对误差。 MAPE 也可以被认为是 MAE 的加权版本。MAPE 的公式如下:
MAPE = 100 % n ∑ i = 1 n ∣ y i ^ − y i y i ∣ \text{MAPE} = \frac{100\%}{n}\sum_{i=1}^n |\frac{\hat{y_i} - y_i}{y_i}| MAPE=n100%i=1nyiyi^yi

对于 MAPE,其样本的权重与其真实的目标成反比。

请注意,如果异常值具有非常非常小的值,则 MAPE 将非常偏向于它,因为此异常值将具有最高权重。

平均绝对百分比误差是通过将实际值与预测值之间的差值除以实际值来计算的。MAPE 也称为平均绝对百分比偏差,随着误差的增加而线性增加。MAPE 越小,模型性能越好。

优点:

  • MAPE与变量的规模无关,因为它的误差估计是以百分比为单位的。
  • 所有错误都在一个共同的尺度上标准化,很容易理解。
  • MAPE避免了正值和负值相互抵消的问题。

缺点:

  • 分母值为零时,面临着“除以零”的问题。
  • MAPE对数值较小的误差比对数值大的误差错误的惩罚更多。
  • 因为使用除法运算,所欲对于相同的误差,实际值的变化将导致损失的差异。
import numpy as np

# 平均绝对百分误差 MAPE
def MAPE(true, pred):
    true = true + 0.1  # 避免0值
    diff = np.abs(np.array(true) - np.array(pred))
    return np.mean(diff / np.abs(true))

# 或者
MAPE = np.mean(np.abs((y_pred - y_true) / y_true)) * 100

# 或者
def mean_absolute_percentage_error(true, pred):  
    abs_error = (np.abs(true - pred)) / true  
    sum_abs_error = np.sum(abs_error)  
    mape_loss = (sum_abs_error / true.size) * 100  
    return mape_loss  

# 或者
MAPE = np.mean(np.abs((y - y_hat) / y)) * 100

# 或者
MAPE = metrics.mean_absolute_percentage_error(y, y_hat)

1.9.1 对称平均绝对百分比误差(Symmetric Mean Absolute Percentage Error,SMAPE)

SMAPE 与 MAPE 相比,加了对称,其实就是将分母变为了真实值和预测值的中值。和 MAPE 的用法一样,范围 [0, + ∞ +\infty +),MAPE 为 0% 表示完美模型,MAPE 大于 100% 则表示劣质模型。

注: 当真实值有数据等于 0,而预测值也等于 0 时,存在分母 0 除问题,该公式不可用!

# SMAPE
def smape(y_true, y_pred):

    res_smape = 2.0 * np.mean(np.abs(y_pred - y_true) / (np.abs(y_pred) + np.abs(y_true))) * 100

    return res_smape

1.10 均方根平方对数误差 (Root Mean Squared Logarithmic Error, RMSLE)

均方根平方对数误差只是以对数标度计算的 RMSE,公式如下:
R M S L E = 1 N ∑ i = 1 N ( l o g ( y i + 1 ) − l o g ( y i ^ + 1 ) ) 2 = R M S E ( l o g ( y i + 1 ) , l o g ( y i ^ + 1 ) ) = M S E ( l o g ( y i + 1 ) , l o g ( y i ^ + 1 ) ) RMSLE = \sqrt{\frac{1}{N}\sum_{i=1}^N(log(y_i + 1) - log(\hat{y_i} + 1))^2} = RMSE(log(y_i + 1), log(\hat{y_i} + 1)) = \sqrt{MSE(log(y_i + 1), log(\hat{y_i} + 1))} RMSLE=N1i=1N(log(yi+1)log(yi^+1))2 =RMSE(log(yi+1),log(yi^+1))=MSE(log(yi+1),log(yi^+1))

事实上,可以看到,采用预测值和目标值的对数,并计算它们之间的RMSE,就是 RMSLE 。由于对数函数的自变量只能为正,因此,我们需要加入常数保证为正数,1 可以换为其它值。

对数尺度上的 RMSE, 目标值通常非负, 倾向于的预测比目标值更小的值。

1.11 解释方差

解释方差(explained_variance_score)又叫可释方差,公式如下:
explained_variance ( y , y ^ ) = 1 − V a r { y − y ^ } V a r { y } \text{explained\_variance}(y, \hat{y}) = 1 - \frac{Var\{y - \hat{y}\}}{Var\{y\}} explained_variance(y,y^)=1Var{y}Var{yy^}

解释方差度量了模型在给定数据集上变化的比例。拟合的越好值越大,最大为 1。

from sklearn.metrics import explained_variance_score

1.12 中位数绝对误差 (Median absolute error,MedAE)

中位数绝对误差公式如下:
MedAE ( y , y ^ ) = median ( ∣ y 1 − y ^ 1 ∣ , . . . , ∣ y n − y ^ n ∣ ) \text{MedAE}(y, \hat{y}) = \text{median}(|y_1 - \hat{y}_1|, ..., |y_n - \hat {y}_n|) MedAE(y,y^)=median(y1y^1,...,yny^n)
可以明显看出来,MedAE对于噪声点是鲁棒的。

from sklearn.metrics import median_absolute_error

explained_variance_score(y_true, y_pred, sample_weight=None, multioutput=‘uniform_average’) # 回归方差(反应自变量与因变量之间的相关程度)

1.13 Huber Loss

Huber损失是线性和二次评分方法的组合。它有一个超参数 delta,可以根据数据进行调整。对于高于 delta 的值,损失将是线性的(L1 损失),对于低于 delta 的值,损失将是二次的(L2 损失)。它平衡并结合了 MAE(平均绝对误差)和 MSE(均方误差)的良好特性。

优点:

  • 它在零处是可微的。
  • 由于 delta 以上的线性度,异常值得到了正确处理。
  • 可以调整超参数delta以最大限度地提高模型准确性。

缺点:

  • 为了最大限度地提高模型精度,需要优化delta,这是一个迭代过程。
  • 它只能微分一次。
def huber_loss(true, pred, delta):  
    huber_mse = 0.5 * np.square(true - pred)  
    huber_mae = delta * (np.abs(true - pred) - 0.5 * (np.square(delta)))  
    return np.where(np.abs(true - pred) <= delta, huber_mse, huber_mae)  

1.14 Log Cosh Loss

Log cosh 计算误差的双曲余弦的对数。这个函数比二次损失更平滑。它像 MSE 一样工作,但不受大预测误差的影响。

优点:

  • 同时处处可二次微分
  • 比 Huber需要更少的计算

缺点:

  • 适应性较差,因为它遵循固定的比例。
  • 与Huber loss相比,推导更复杂,需要深入研究
def huber_loss(true, pred, delta):  
    diff = np.cosh(pred - delta)  
    diff = np.log(diff)  
    return diff.mean()  

1.15 Quantile Loss

分位数回归损失函数用于预测分位数。分位数是确定组中有多少值低于或高于某个限制的值。它跨预测变量(自变量)的值估计响应变量(因变量)的条件中位数或分位数。

2. 分类指标

分类评价指标有准确率(accuracy)、精确率(precision)、召回率(recall)、AUC面积、F值等。

评价指标主要有accuracy, [precision,recall,F-score,pr曲线],ROC-AUC曲线

2.1. 混淆矩阵 confusion matrix

confusion matrixpositive(predict)negative(predict)
positive(true )TPFN
negative(true)FPTN
  • TP(true positive): 真实值是positive,预测值也是positive的值数量
  • TN(true negative): 真实值是negative,预测值也是negative的值数量
  • FP(false positive): 真实值是negative,预测值是positive的值数量
  • FN(false negative): 真是只是positive,预测值是negative的值数量
from sklearn import metric

# 通过计算混淆矩阵来评估分类的准确性 返回混淆矩阵
CM = metric.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
print(CM)

python 实现绘制混淆矩阵

def confusion_matrix_(y_pred,y_true):
    '''
    params:
        y_pred:预测值
        y_true:真实值
    result:
        绘制混淆矩阵和准确率、精确率、F1值
    '''
    CM = confusion_matrix(y_true,y_pred)
    
    fig = plt.figure(figsize=(12,6))
    
    fig.suptitle(r'Confusion Matrix')
    #画热力图
    ax1 = fig.add_subplot(1,2,1)
    sns.heatmap(CM,annot=True,cmap='Blues',linewidths=0.5,ax=ax1)
    ax1.set_xlabel('predicate')
    ax1.set_ylabel('true')
    
    #文本显示指标
    
    (tn,fp,fn,tp) = CM.ravel()
    acc = format_2(accuracy_score(y_true, y_pred))
    pre0 = format_2(tn/(fn+tn)); pre1 = format_2(tp/(tp+fp))
    recall0 = format_2(tn/(fp+tn)); recall1 = format_2(tp/(tp+fn))
    f10 = format_2(2*tn/(2*tn+fp+fn))
    f11 = format_2(2*tp/(2*tp+fp+fn))
    col_labels = ['precision','recall','F1']
    row_labels = [' '*4+'0'+' '*4,' '*4+'1'+' '*4]
    table_vals = [[pre0,recall0,f10],[pre1,recall1,f11]]
    ax2 = fig.add_subplot(1,2,2)
    ax2.table(cellText=table_vals,rowLabels=row_labels,
              colLabels=col_labels,loc='center')
    ax2.text(0.35,0.6,
             r'''
            accuracy: {acc}
              '''.format(acc=acc),
        horizontalalignment='center',
        verticalalignment='center',
        fontsize=20, color='black',
        transform=ax2.transAxes)
    ax2.axis('off')
    ax2.set_xticks([])
    ax2.set_yticks([])
    plt.show()   

2.2 准确率/精度 Accuracy

也称精度, 分类准确的样本数占该类样本总数的比例,此外,分类错误的样本数占样本总数的比例称为“错误率”(error rate)。

假如, m m m 个样本有 a a a 个样本分类错误。
E = a / m a c c = 1 − a / m Accuracy = 1 N ∑ i = 1 N [ y i ^ = y i ] = T P + T N T P + T N + F P + F N E = a / m \\ acc = 1 - a/m \\ \text{Accuracy} = \frac{1}{N} \sum_{i=1}^N [\hat{y_i} = y_i] = \frac{TP + TN}{TP + TN + FP + FN} E=a/macc=1a/mAccuracy=N1i=1N[yi^=yi]=TP+TN+FP+FNTP+TN

# calculate accuracy
from sklearn import metrics
acc = metrics.accuracy_score(y_test, y_pred)
from sklearn import metrics

# 根据预测得分计算平均精度(AP)
metrics.average_precision_score(y_true, y_score, average=‘macro’, sample_weight=None)

2.2 空准确率 null accuracy

使用样本比例最多的类别进行预测时的准确率。

y_count = np.bincount(y_test)
ii = np.nonzero(y_count)[0]
print(y_count)
zip(ii, y_count[ii])
print('null acc', y_count[0]/ len(y_test) )

2.3 每类的 accuracy

def cal_acc(true_labels, pred_labels):
    '''
    true_labels: like[2,1,4],
    pred_labels: like[1,2,3]
    output: the acc of each class.
    '''
    from collections import Counter
    total = Counter(true_labels)
    keys = np.unique(true_labels)
    acc = {}
    for key in keys:
        acc[key] = 0
    for i in range(len(pred_labels)):
        if pred_labels[i] == true_labels[i]:
            acc[pred_labels[i]] += 1
    for key in keys:
        acc[key] = acc[key] / total[key]
    return acc

2.3 精准率/查准率 precison

精确率:在预测值是positive中,预测对的占比

Precision = T P T P + F P \text{Precision} = \frac{TP}{TP + FP} Precision=TP+FPTP

from sklearn.metrics import precision_score

precision_score(y_true, y_pred)

2.4 召回率/查全率 Recall

Recall = T P T P + F N \text{Recall} = \frac{TP}{TP + FN} Recall=TP+FNTP

from sklearn.metrics import recall_score

r = recall_score(y_true, y_pred)

查全率和查准率是一对矛盾的度量,一般来说,查准率高,查全率往往偏低,查全率高时,查准率往往偏低。例如,若希望将好瓜尽可能多地选出来,可通过增加选瓜的数量实现,如果将所有西瓜都选上,那么所有的好瓜也必然都被选上了,查准率就会降低,若希望选出的瓜中好瓜比例尽可能高,则可挑选最有把握的瓜,但这样就难免会漏掉不少好瓜,使得查全率较低,通常只有在一些简单任务中,才可能查全率和查准率都很高。

2.5 P-R 曲线

根据学习器的预测结果对样例进行排序(预测通常为[0,1]之间的概率,通过划分阈值判断为正还是为反样例),排在前面的是学习器认为“最可能”是正例的样本,排在最后的则是学习器认为“最不可能”是正例的样本.按此顺序逐个把样本作为正例进行预测,则每次可以计算出当前的查全率、查准率.以查准率为纵轴、查全率为横轴作图,就得到了查准率-查全率曲线,简称“P-R曲线”,显示该曲线的图称为“P-R图”﹒图2.3给出了一个示意图.

P-R 图直观地显示出学习器在样本总体上的查全率、查准率.在进行比较时,若一个学习器的P-R曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者,例如图2.3中学习器A的性能优于学习器C;如果两个学习器的P-R曲线发生了交叉,例如图2.3中的A与B,则难以一般性地断言两者孰优孰劣,只能在具体的查准率或查全率条件下进行比较.然而,在很多情形下,人们往往仍希望把学习器A与B比出个高低.这时一个比较合理的判据是比较P-R曲线下面积的大小,它在一定程度上表征了学习器在查准率和查全率上取得相对“双高”的比例.但这个值不太容易估算,因此,人们设计了一些综合考虑查准率、查全率的性能度量.

“平衡点” (Break-Event Point,BEP) 就是这样一个度量,它是“查准率=查全率”时的取值,例如图 2.3 中学习器 C 的 BEP 是 0.64,而基于 BEP 的比较,可认为学习器 A 优于 B.

2.6 F1 score

F1 score:综合了precision与recall的产出的结果。取值范围从[0,1],1代表模型的输出最好(全部预测对),0代表模型的输出结果最差
1 F 1 = 1 2 ⋅ ( 1 P + 1 R ) \frac{1}{F1} = \frac{1}{2} ·\left(\frac{1}{P} + \frac{1}{R} \right) F11=21(P1+R1)

F 1 = 2 × P × R P + R = 2 × T P 样例总数 + T P − T N F1 = \frac{2 × P × R}{P + R} = \frac{2 × TP}{样例总数 + TP - TN} F1=P+R2×P×R=样例总数+TPTN2×TP

from sklearn.metrics import f1_score

f1 = f1_score(y_true, y_pred)

2.7 ROC 与 AUC

FPR: 假正例率/假阳率(ROC的 x 轴);
FPR 的含义是,把负类错误预测为正类的个数占总共负类的个数的比例。

F P R = F P T N + F P FPR = \frac{FP}{TN + FP} FPR=TN+FPFP

TPR: 真正例率/真阳率(ROC的 y 轴);
TPR 的含义是,正确预测为正类的个数占总共预测正类的个数的比例。
T P R = T P T P + F N TPR = \frac{TP}{TP + FN} TPR=TP+FNTP

ROC,Receiver Operating Characteristic Curve, 受试者工作特征曲线,曲线的纵轴是 “真正例率”(True Positive Rate,简称 TPR),横轴是“假正例率”(False Positive Rate, 简称 FPR)

图 2.4(a) 给出了一个示意图,显然,对角线对应于“随机猜测”模型, 而点(0,1) 则对应于将所有正例排在所有反例之前的“理想模型”.

现实任务中通常是利用有限个测试样例来绘制 ROC 图,此时仅能获得有限个(真正例率,假正例率)坐标对,无法产生图 2.4(a) 中的光滑 ROC 曲线,只能绘制出如图 2.4(b) 所示的近似 ROC 曲线。绘图过程很简单:给定 m + m^+ m+ 个正例和 m − m^- m 个反例,根据学习器预测结果对样例进行排序,然后把分类阈值设为最大,即把所有样例均预测为反例,此时真正例率和假正例率均为 0,在坐标 (0,0) 处标记一个点。然后,将分类阈值依次设为每个样例的预测值,即依次将每个样例划分为正例。设前一个标记点坐标为 ( x , y ) (x, y) (x,y),当前若为真正例,则对应标记点的坐标为 ( x , y + 1 m + ) (x,y + \frac{1}{m^+}) (x,y+m+1);当前若为假正例,则对应标记点的坐标为 ( x + 1 m − − , y ) (x + \frac{1}{m^-} -,y) (x+m1,y),然后用线段连接相邻点即得。

特殊的几个点:

  • (0,0):FPR=TPR=0 ,即所有样本都被预测为阴性样本 (阈值设定为最高的时候)
  • (1,1):FPR=TPR=1,所有样本都被预测为阳性样本 (阈值设定为最低的时候);
  • (1,0):FPR=1,TPR=0,所有阳性都被预测为阴性,而所有阳性都没被预测出来,它成功的避开了所有正确答案。
  • (0,1):FPR=0,TPR=1,这是一个完美的分类器,它将所有样本都正确分类。

所以经过上述分析,我们可以断言,ROC曲线越接近左上角,该分类器的性能越好,意味着分类器在假阳率很低的同时获得了很高的真阳率。

进行学习器的比较时,与P-R图相似,若一个学习器的 ROC 曲线被另一个学习器的曲线完全 “包住”,则可断言后者的性能优于前者;若两个学习器的 ROC 曲线发生交叉,则难以一般性地断言两者孰优孰劣。此时如果一定要进行比较,则较为合理的判据是比较 ROC 曲线下的面积,即 AUC (Area UnderROC Curve),如图 2.4 所示。

从定义可知,AUC 可通过对 ROC 曲线下各部分的面积求和而得。假定 ROC 曲线是由坐标为 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } \{(x_1, y_1),(x_2, y_2),. . . , (x_m, y_m)\} {(x1,y1),(x2,y2),...,(xm,ym)} 的点按序连接而形成 ( x 1 = 0 , x m = 1 ) (x_1=0,x_m = 1) (x1=0,xm=1);参见图 2.4(b),则 A U C AUC AUC 可估算为

形式化地看,AUC 考虑的是样本预测的排序质量,因此它与排序误差有紧密联系。(因为是在1x1的方格里求面积,AUC必在0~1之间。)

从 AUC 判断分类器(预测模型)优劣的标准:

  • AUC = 1,是完美分类器,采用这个预测模型时,存在至少一个阈值能得出完美预测。绝大多数预测的场合,不存在完美分类器。
  • 0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
  • AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
  • AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

在这里插入图片描述

ROC 曲线

from sklearn import metric
# 计算 ROC 曲线,既真阳率、假阳率等
FPR,TPR,thresholds = metrics.roc_curve(y_true, y_pred)

AUC 曲线

from sklearn import metric

# 第一种方式,已知 FPR、TPR 计算 AUC 值(与上述 ROC 联合使用)
AUC = metrics.auc(FPR,TPR)
print(AUC)

# 第二种方式
AUC = metrics.roc_auc_score(y_true, y_pred)

AUC 曲线绘制

def auc_roc_ks_(y_predproab,y_true,plot=True):
    '''
    params:
        y_predproab:预测值概率
        y_true:真实值
        plot:是否绘制roc曲线,默认绘制
    result:
        绘制roc曲线,并显示auc和ks
    '''  
    fpr,tpr,threshold = roc_curve(y_true,y_predproab)
    auc_ = format_4(auc(fpr,tpr))
    ks = format_4(max(abs(tpr - fpr)))
    if plot:
        plt.figure(figsize=(6,6))
        plt.title('ROC_AUC_KS',fontsize=25)
        plt.plot(fpr,tpr,color='navy',lw=2,
                 label='auc:{}'.format(auc_))
        plt.plot([0,1],[0,1],color='darkorange',lw=2,linestyle='--')
        #标记ks
        gap = abs(fpr-tpr)
        plt.plot(fpr,gap,linewidth=2,color='r',label='ks:{}'.format(ks))
        plt.xlabel('False Positive Rate',fontsize=20)
        plt.ylabel('True Positiobe Rate',fontsize=20)
        plt.legend(loc='best')
        plt.show()
    else:
        print('auc:{auc_}\nks:{ks}'.format(auc_=auc_,ks=ks))

总结

  • ROC曲线反映模型在选取不同阈值时的敏感性和精确性,所以能很容易查出任意阈值对学习起的泛化性能影响,有助于选择最佳阈值
  • ROC曲线越靠近左上角,模型的查全率越高。
  • 测试集样本分布发生变化时,ROC曲线能够保持不变。因为ROC、AUC同时考虑了学习器对正、负样本的分类能力,所以对样本是否分布均衡并不敏感。
  • ROC、AUC都只适合于二分类

2.8 LogLoss:对数损失(logarithmic loss)

当有一个模型输出概率时,会根据预测与实际标签的偏差来考虑预测的不确定性。

二分类任务:

L o g L o s s = − 1 N ∑ i = 1 N y i l o g ( y i ^ ) + ( 1 − y i ) l o g ( 1 − y i ^ ) LogLoss = -\frac{1}{N}\sum_{i=1}^N y_i log(\hat{y_i}) + (1 - y_i)log(1 - \hat{y_i}) LogLoss=N1i=1Nyilog(yi^)+(1yi)log(1yi^)

多分类任务:
L o g L o s s = − 1 N ∑ i = 1 N ∑ i = 1 L y i l l o g ( y i l ^ ) LogLoss = -\frac{1}{N}\sum_{i = 1}^N \sum_{i=1}^L y_{il} log(\hat{y_{il}}) LogLoss=N1i=1Ni=1Lyillog(yil^)

最佳常量:设定 α i \alpha_i αi 为第 i i i 个类别的频率。

from sklearn import metric

# 对数损耗,又称逻辑损耗或交叉熵损耗
loss = metric.log_loss(y_true, y_pred, eps=1e-15, normalize=True, sample_weight=None, labels=None)

2.9 Brier分数

当任务本质上是二元分类时,通常使用Brier分数。 它只是实际值和预测值之间的平方差。 对于N组样本,我们将其取平均值。

from sklearn import metric

# :The smaller the Brier score, the better.
metric.brier_score_loss(y_true, y_prob, sample_weight=None, pos_label=None)

References

[1] 回归评价指标(MSE、RMSE、MAE、R-Squared、拟合优度)

[2] 回归评价指标:MSE、RMSE、MAE、R2、Adjusted R2

[3] 回归模型评估指标(MAE、MSE、RMSE、R²、MAPE)

[4] 回顾及总结–评价指标(回归指标)

[5] 【推荐收藏】机器学习12种回归评价指标(附Python代码)

[6] 回归评价指标MSE、RMSE、MAE、MAPE及python实现

[7] (一)常见的回归评价指标及代码实现与应用

[8] 机器学习中的预测评价指标MSE、RMSE、MAE、MAPE、SMAPE

[9] Python sklearn机器学习各种评价指标——Sklearn.metrics简介及应用示例

[10] 机器学习模型性能评估指标总结以及python实现

[11] 机器学习中分类任务的常用评估指标和python代码实现

[12] 机器学习分类的几种评价指标:准确率Accuracy, AUC, Precision, Recall, F1,MAPE,SMAPE

[13] 机器学习模型评价指标ROC-AUC

[14] 机器学习——分类评价指标

[15] 机器学习篇-指标:AUC

[16] 机器学习模型的评价指标和方法(附代码)

[17] 数据竞赛评价指标优化

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值