Press "Enter" to skip to content

机器学习初学者都应该知道的5类回归损失函数

来源:

 

https://heartbeat.fritz.ai/5-regression-loss-functions-all-machine-learners-should-know-4fb140e9d4b0

 

翻译:石头

 

机器学习中的所有算法都依赖于最小化或最大化一个函数,我们称之为“目标函数”。最小化的函数称为“损失函数”,损失函数衡量的是模型预测预期结果的能力,最常用的最小化损失函数的方法是“梯度下降法”,把损失函数想象成起伏的山脉,梯度下降法就像从山上滑下来到达最低点。

 

没有一个损失函数适用于所有类型的数据,它取决于许多因素,包括异常值的存在,机器学习算法的选择,梯度下降法的时间效率和预测的置信度等。本文的目的是了解不同的损失函数以及它们是如何帮助数据科学家。

 

损失函数大致可分为两类:分类损失和回归损失。回归函数预测数量,分类函数预测标签,常用的回归损失函数和分类损失函数如下图:

 

 

在这篇文章中,小编主要介绍回归损失函数。

 

回归损失

 

1. 均方误差,二次损失,L2损失

 

均方误差(MSE)是最常用的回归损失函数,MSE是目标变量和预测值之间距离的平方和,公式如下:

 

 

下面是一个MSE函数的图,其中真实的目标值是100,预测值在-10000到1000之间,MSE损失值(y轴)在预测(x轴) = 100 时达到最小值,损失之范围在0到∞之间。

 

 

2. 平均绝对误差,L1损失

 

平均绝对误差(MAE)是用于回归模型的另一个损失函数,MAE是目标值和预测值之间绝对差的总和的平均值。

 

 

MAE损失函数曲线图如下:

 

 

MSE与MAE的比较(L2损失与L1损失的比较)

 

简而言之,使用平方误差更容易解决,但是使用绝对误差更有鲁棒性,让我们看看为什幺。

 

当我们训练一个机器学习模型时,我们的目标是找到最小化损失函数的点,当然,当预测值正好等于真实值时,两个函数达到最小值。

 

下面是这两种方法的Python代码的快速实现,我们可以编写自己的函数,也可以使用sklearn的内置度量函数:

 

# true: Array of true target variable
# pred: Array of predictions
def mse(true, pred):
    return np.sum((true - pred)**2)
    
 def mae(true, pred):
  return np.sum(np.abs(true - pred))
 
 # also available in sklearn
 
 from sklearn.metrics import mean_squared_error
 from sklearn.metrics import mean_absolute_error

 

让我们看看两种情况下的MAE和RMSE的值比较 , 其中RMSE是MSE的平方根,使RMSE和MAE是同一尺度上的比较。

 

如下图的第一种情况,预测值接近真实值,误差在观测值之间的方差很小:

 

 

如下图的第二种情况,观测值之间出现离群值(outlier),误差很大。

 

 

我们从中观察到什幺呢? 它如何帮助我们选择使用哪个损失函数?

 

由于MSE平方了误差(y – y_predicted = e),若e大于1,误差(e)的将会增加很多。如果我们有一个离群值,e的值会大大增大,且MSE的值会远远大于e,这将会使MSE损失模型比MAE损失模型给与离散值更多的权重。若将RMSE作为损失的模型进行调整,损失模型将最小化异常点,而牺牲其他观测值,这回降低其整体性能。

 

如果训练数据被异常值破坏,MAE损失是有用的,也就是说 我们在训练数据中错误地收集了不现实的极大的负值和正值,而不是在测试环境中。

 

直观一点的说,我们可以这样想:如果我们只需要对所有试图最小化MSE的观测结果给出一个预测,那幺这个预测应该是所有目标值的平均值。但如果我们试着最小化MAE,这个预测就是所有观测值的中位数。我们不难知道中位数比平均值对异常值更稳健,因此使得MAE比MSE对异常值更稳健。

 

MAE损失函数的一个大问题使: 它的梯度始终使相同的,这意味着即使损失值很小,梯度也会很大。 这在模型学习过程中没有好处,为了解决这个问题,我们可以使用动态学习率,它会随着我们接近最小值而降低。MSE在这种情况下表现得很好,即使在固定的学习速率也会收敛。当损失值较大时,MSE损失的梯度较高;当损失接近0时,MSE损失的梯度下降,时期在训练结束时更加精确(如下图)

 

 

如何选择使用哪个损失函数

 

如果异常值表示对业务很重要,那幺我们应该使用MSE,另一方面,如果我们认为异常值只是代表无用的数据,那幺我们应该选择MAE作为损失函数,MAE和MSE也分别称为L1和L2损失。

 

MAE和MSE都存在的问题

 

在某些情况下,两种损失函数都不能给出令人满意的预测。例如,如果我们数据中90%的观测值的目标值使150,其余10%的目标值在0~30之间。然后,一个以MAE作为损失的模型预测所有观测值为150,忽略10%的异常情况,因为该模型的作用接近于中值算法。

 

同样的情况下,使用MSE的模型会给出许多0~30范围内的预测,因为它会向异常值倾斜。在许多业务案例中,这两个结果都是不受欢迎的。

 

这种情况下该怎幺办?

 

一种简单的解决办法使转换目标变量,另一种方法使尝试一种不同的损失函数,这就是小编将要介绍第三个损失函数Huber损失的动机。

 

3. Huber损失,平滑平均绝对误差(Smooth Mean Absolute Error)

 

与平方误差损失相比,Huber损失对数据中的异常值不那幺敏感,它在0处也是可微的。当误差很小的时候就变成了二次误差,误差有多小才能变成二次函数取决于超参数  (delta), 这个超参数是可调的。

 

当超参数   ~ 0 时,Huber损失方法接近MAE;当超参数   ~ ∞ 时,Huber损失方法接近MSE。

 

 

Huber的曲线如下图,其中不同颜色的曲线表示不同的超参数(真实值等于0)。

 

 

超参数  的选择是很关键的,因为它决定了你愿意考虑哪些异常值,大于 的残差用L1最小化,因为L1对较大的异常值不太敏感,而小于  的残差用L2最小化。

 

为什幺使用Huber Loss?

 

使用MAE训练神经网络的一个大问题是它的梯度是一个比较大的常数,这可能导致在使用梯度下降训练结束时,丢失了最小值。对于MSE,梯度随着损失函数接近其最小值而减小,从而更容易找到最小值。

 

Huber损失在这种情况下是很有帮助的,因为它在最小值附近减小了梯度,而且比MSE更健壮。因此,Huber损失结合了MSE和MAE的优点,然而,Huber损失的问题是我们可能需要训练超参数   ,这是一个迭代的过程。

 

4. Log-Cosh损失

 

Log-Cosh是回归任务中使用的另一个函数,它比L2更平滑,Log-cosh是预测误差的双曲线余弦的对数。

 

 

Log-Cosh损失函数与预测值的曲线(真实值等于0):

 

 

优点: 当 x 较小时,log(cosh(x))近似等于(x**2)/2;x 较大时,近似等于 abs(x) – log(2)。这意味这“logcosh”的工作原理与MSE非常相似,但不会受到偶尔出现异常值的影响。它具有Huber损失的所有优点,且在任何情况下都是可微的。

 

为什幺我们需要二阶导 ?

 

许多ML模型实现(如XGBoost)都使用牛顿方法来寻找最优值,这就是为什幺使用二阶微分(Hessian)的原因。对于像XGBoost这样的ML框架,两次可微函数更受欢迎。

 

xgboost的目标函数:

 

 

其中g_i和h_i分别是损失函数l的一阶微分和二阶微分:

 

 

但是logcosh损失并不完美,当预测值与真实值偏差较大时,梯度和二阶微分是一个常数,不符合xgboost的分割条件 。

 

Huber和Log-cosh损失函数的Python代码:

 

# huber loss
def huber(true, pred, delta):
    loss = np.where(np.abs(true-pred) < delta , 0.5*((true-pred)**2), delta*np.abs(true - pred) - 0.5*(delta**2))
    return np.sum(loss)
# log cosh loss
def logcosh(true, pred):
    loss = np.log(np.cosh(pred - true))
    return np.sum(loss)

 

5. 分位数损失

 

在现实世界的大多数预测问题中,我们常常对预测中的不确定性感兴趣。了解预测的范围(而不是仅了解点估计),可以极大地改进许多业务问题的决策过程。

 

当我们想要预测一个区间而不是仅仅预测一个点时,分位数损失函数是有用的。最小二乘回归的预测区间是基于残差(y-y_hat)在各自变量值之间具有恒定方差的假设。

 

我们既不能相信违背这一假设的线性回归模型,也不能抛弃将线性回归模型作为基准来拟合的想法,因为使用非线性函数或基于树构建模型并非更好。这就是分位数损失和分位数回归发挥作用的地方,基于分位数损失的回归为残差提供了合理的预测区间,即使残差的方差不是常数或非正态分布。

 

让我们举一个例子,以更好的理解为什幺基于分位数损失的回归异方差数据中表现良好。

 

分位数回归于普通最小二乘法回归

 

如下图的两类数据,左图为同方差的数据,右图为异方差的数据:

 

 

运用最小二乘法后的线性回归结果:

 

 

分位数为0.05和0.95的分位数回归:

 

 

虚线表示基于0.05和0.95的分位数损失的回归

 

理解分位数损失函数

 

分位数的回归是在给定预测变量的条件下,估计响应变量的条件分位数。分位数损失实际上是MAE的扩展,当分位数为0.5时,它就是MAE。

 

这个想法是根据我们想要给予正误差或负误差更多的值来选择分位数值,损失函数通过分位数来给高估的预测值或低估的预测值不同的惩罚权重,比如设置分位数 γ = 0.25时,分位数损失函数会给高估的预测值更多的惩罚,尽量保持预测值略低于中位数。

 

分位数损失函数:

 

 

分位数 γ 的值在0和1之间,预测值和分位数回归损失函数的关系如下图(真实值等于0)

 

 

我们也可以使用这个损失函数来计算神经网络和基于树模型的预测区间,下面是一个用于梯度增强树回归的sklearn实现实例:

 

 

上图的90%的预测值的置信区间的上限为分位数等于0.95,下限为分位数等于0.05。

 

四种回归损失函数的比较

 

为了比较上述损失函数的性质,模拟sinc函数数据,并叠加了两类噪声模拟数据:高斯噪声组件ε ~ N(0, σ2) 和脉冲噪声组件 ξ ~ Bern(p)。为了说明鲁棒性,我们加入了脉冲噪声项,下面是使用不同的损失函数的GBM拟合回归的结果:

 

 

其中A表示MSE损失方程,B表示MAE损失方程,C表示Huber损失方程,D表示分位数损失方程,E表示原始数据sinc(x)方程,F表示MSE损失和MAE损失的拟合结果,G表示不同  时,Huber损失的拟合结果,H表示分位数损失的拟合结果。

 

分析上面不同损失的回归结果,可以得到一些结论:

 

1)带有MAE损失模型的预测受脉冲噪声的影响较小,而带有MSE损失模型的预测由于噪声的原因而略有偏差。

 

2)预测结果对带有huber损失模型的超参数取值不敏感。

 

3)分位数损失可以很好地估计相应的置信水平。

 

所有回归损失函数画在一张图上:

 

 

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注