作者:Prince Grover编译:ronghuaiyang
导读
为模型选择合适的损失函数,让模型具有最好的效果。
机器学习中的所有算法都依赖于函数的最小化或最大化,我们称之为“目标函数”。一组最小化的函数称为“损失函数”。损失函数是衡量预测模型在预测预期结果方面做得有多好。求函数最小值的一种常用方法是“梯度下降法”。把损失函数想象成起伏的山,而梯度下降就像从山上滑下来到达最低点。
没有一个单一的损失函数适用于所有类型的数据。它取决于许多因素,包括异常值的存在、机器学习算法的选择、梯度下降的时间效率、求导数的易用性和预测的置信度。本系列博客的目的是了解不同的损失以及每种损失如何帮助数据科学家。
损失函数可以大致分为两类:分类和回归损失。在这篇文章中,我主要关注回归损失。在以后的文章中,我将讨论其他类别的损失。如果我忘记了什么,请在评论中告诉我。此外,本博客所展示的所有代码和图表均可在 这里中找到。
![cb5bcf6fb8372cf4453684e06510218f.png](https://i-blog.csdnimg.cn/blog_migrate/2898fa1e267c287ee9e9ca5cd1023222.jpeg)
回归函数预测的数值,分类函数预测的是标签
回归损失
1. 均方误差,二次型损失,L2损失
均方误差(Mean Square Error, MSE)是最常用的回归损失函数。MSE是目标变量与预测值之间距离的平方和。
![7b3e7d21f02ee656b4c625a68dae0936.png](https://i-blog.csdnimg.cn/blog_migrate/c0d7669b1c502763ce7447babed11e67.jpeg)
下面是一个MSE函数的图,其中真实目标值为100,预测值在-10,000到10,000之间。MSE损失(y轴)在预测(x轴)= 100时达到最小值。范围是0到∞。
![18726f3c73107f2fc93a51d506db626b.png](https://i-blog.csdnimg.cn/blog_migrate/96b3d9487ed721df209f5659bab006f6.jpeg)
Plot of MSE Loss (Y-axis) vs. Predictions (X-axis)
2. 平均绝对误差,L1损失
平均绝对误差(MAE)是回归模型中使用的另一个损失函数。MAE是目标变量和预测变量之间的绝对差值之和。所以它测量的是一组预测的平均误差大小,而不考虑它们的方向。(如果我们也考虑方向,那就叫做平均偏差误差(Mean Bias Error, MBE),它是残差/误差的和)。范围也是0到∞。
![c0c9013f0564b665020c9f23844952b9.png](https://i-blog.csdnimg.cn/blog_migrate/248b37806e19e3d4fa441c44b02248f3.jpeg)
![3dcc36f08036b6de461420cdb6a1c085.png](https://i-blog.csdnimg.cn/blog_migrate/ae8371ec25042f2b3414c6569e44b17e.jpeg)
Plot of MAE Loss (Y-axis) vs. Predictions (X-axis)
MSE vs. MAE (L2 loss vs L1 loss)
简而言之,使用平方误差更容易,但是使用绝对误差对异常值更有鲁棒性。我们来理解一下为什么!
当我们训练机器学习模型时,我们的目标是找到使损失函数最小化的点。当然,当预测值恰好等于真实值时,两个函数都达到最小值。
下面快速回顾一下这两种方法的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
让我们看看2种情况下MAE和均方根误差的值(RMSE,也就是MSE的平方根,使其与MAE处于相同的规模)。在第一种情况下,预测值接近真实值,误差在观测值之间的方差很小。在第二种情况下,有一个异常值,误差很大。
![93512918b0704dc718ee93d5a6f79cbd.png](https://i-blog.csdnimg.cn/blog_migrate/759649941a3aa10cfef807bd7d7663f8.jpeg)
左: 误差很接近 右: 有一个误差和其他差别很大
我们从中观察到什么,它如何帮助我们选择使用哪种损失函数?
由于MSE平方误差(y - y_prediction = e),所以如果e > 1,误差(e)的值会增加很多。如果我们有一个异常数据,e的值会变得很大并且e²>>e。这将使MSE损失模型比MAE损失模型给予离群值更多的权重。在上面的第二种情况中,以RMSE为损失的模型将被调整,以牺牲其他常见的例子来最小化单个的离群值情况,这将降低它的总体能力。
如果训练数据被异常值破坏(例如,我们在训练环境中错误地接收到巨大的负/正值,但在测试环境中却没有),那么MAE损失是有用的。
直觉上,我们可以这样想:如果我们只需要对所有试图最小化MSE的观测结果给出一个预测,那么这个预测应该是所有目标值的平均值。但是如果我们试图最小化MAE,这个预测将是所有观测值的中值。我们知道中值比平均值更对异常值更健壮,这使得MAE比MSE对异常值更健壮。
使用MAE loss的一个大问题是(尤其是对于神经网络),它的梯度始终是相同的,这意味着即使损失值很小,梯度也会很大。这不利于学习。为了解决这个问题,我们可以使用动态学习速率,当我们接近最小值时,动态学习速率会降低。MSE在这种情况下表现良好,即使有固定的学习速率也会收敛。MSE损失的梯度在损失值较大时较高,在损失接近0时减小,使得训练结束时更加精确(见下图)。
![b54b7c448003bf495c9c2da62549106c.png](https://i-blog.csdnimg.cn/blog_migrate/a13066eb9af467bd7ae31d2bd28c3b5f.jpeg)
决定使用哪个损失函数 如果异常值代表对业务重要而且是应该检测的异常,那么我们应该使用MSE。另一方面,如果我们认为离群值只是代表损坏的数据,那么我们应该选择MAE作为损失。
我建议阅读这篇文章,并结合一项不错的研究比较使用L1 loss和L2 loss的回归模型的性能,研究是否存在异常值。记住,L1和L2损失只是MAE和MSE的另一个名称。
L1损失对异常值的鲁棒性更强,但其导数不是连续的,使得求解效率低下。L2损耗对异常值很敏感,但给出了一个更稳定、更封闭的解(通过将其导数设置为0.)
两者都有问题:在某些情况下,损失函数都不能给出理想的预测。例如,如果我们的数据中90%的观测值的真实目标值为150,其余10%的目标值在0-30之间。然后,一个以MAE为损失的模型可能预测所有观测值为150,忽略10%的异常情况,因为它将试图接近中值。在同样的情况下,使用MSE的模型会给出0到30范围内的许多预测,因为它会偏向于离群值。这两种结果在许多业务案例中都是不可取的。
在这种情况下该怎么办?一个简单的解决方法是转换目标变量。另一种方法是尝试不同的损失函数。这就是我们的第三个损失函数背后的动机,Huber损失。
3. Huber Loss, 平滑的平均绝对误差
Huber loss对数据中异常值的敏感性小于平方误差损失。它在0处也是可微的。它基本上是绝对误差,当误差很小的时候,它变成了二次函数。多小的时候变成二次误差取决于超参数,,这是可调整的。Huber损失方法当~ 0时为MAE,当~∞时为MSE
![f485cd819e0e93e633000095cac765ba.png](https://i-blog.csdnimg.cn/blog_migrate/6ed88f083156fce9f2a1a5cb3af3b3fa.jpeg)
![370f826e010e508e1203ddfd5b1c9cb0.png](https://i-blog.csdnimg.cn/blog_migrate/e477f7ffe6e9069b7dad1b1103244aeb.jpeg)
Plot of Hoss Loss (Y-axis) vs. Predictions (X-axis
delta的选择非常关键,因为它决定了你愿意将什么视为异常值。大于delta的残差用L1最小化(L1对大的异常值不太敏感),而小于delta的残差用L2“适当地”最小化。
为什么使用Huber损失?使用MAE训练神经网络的一个大问题是它的梯度经常很大,这会导致在使用梯度下降法训练结束时会错过最小值。对于MSE,梯度随着损失接近最小值而减小,使其更加精确。
Huber损失在这种情况下非常有用,因为它会围绕着减小梯度的最小值曲线。它比MSE对异常值更有效。因此,它结合了MSE和MAE的优良性能。然而,Huber损失的问题是我们可能需要训练超参数delta,这是一个迭代过程。
4. Log-Cosh Loss
Log-cosh是回归任务中使用的另一个比L2更平滑的函数。Log-cosh是预测误差的双曲余弦的对数。
![0ba0b2fb982586e7ec85a45710f9f5a2.png](https://i-blog.csdnimg.cn/blog_migrate/7aba88c7cc31b0eb5187ef01ebfb5bec.jpeg)
Plot of Log-cosh Loss (Y-axis) vs. Predictions (X-
优点: log(cosh(x))对于小的x,大约等于(x ** 2) / 2对,对于大的x,大约等于abs(x) - log(2)。这意味着logcosh的工作原理与均方误差类似,但不会受到偶尔出现的严重错误预测的太大影响。它具有Huber损失的所有优点,不像Huber损失,它在任何地方都是二阶可微的。
为什么我们需要二阶导数?许多ML模型的实现,如XGBoost,都使用牛顿法来寻找最优解,这就是为什么需要二阶导数(Hessian)。对于像XGBoost这样的ML框架,二阶可微的函数更为有利。
![10237c5774dff5962c0624fbcb4bd290.png](https://i-blog.csdnimg.cn/blog_migrate/cf0a17d3cf3eeeb978197e228bd45518.jpeg)
XgBoost中用的目标函数,注意,依赖一阶和二阶导数
但是log-cosh损失并不是完美的。它仍然存在梯度和hessian问题,因为对于偏离目标非常大的的预测是恒定的,因此导致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)在自变量值之间具有恒定方差的假设。我们不能相信违反这一假设的线性回归模型。我们也不能抛弃将线性回归模型拟合为基线的想法,认为使用非线性函数或基于树的模型对这种情况进行建模总是更好的。这就是分位数损失和分位数回归可以弥补的地方,因为基于分位数损失的回归甚至为非恒定方差或非正态分布的残差提供了合理的预测区间。
让我们看一个例子,以更好地理解为什么基于分位数损失的回归在异方差数据中表现良好。
分位数回归vs.普通最小二乘回归
![b47e637db371595bac05ffaf114407be.png](https://i-blog.csdnimg.cn/blog_migrate/366137b6dc646e5325a2a0041139cbb6.jpeg)
左: X1和Y是线性关系,具有固定的方差。右:X2和Y是线性关系,但是Y的方差随着X2增加(异方差性
![ac685cf3d08b9c23181598d3713b0bbc.png](https://i-blog.csdnimg.cn/blog_migrate/ab31a359c6d31dfbfa459f95f3aa8f99.jpeg)
橘色线表示了两种情况的OLS估计
![9c11c8ad0d5fcd492e6586866e87adc5.png](https://i-blog.csdnimg.cn/blog_migrate/c56c6cf8d403c0b6bd25ff125258175d.jpeg)
分位数回归。虚线表示基于0.05和0.09分位数损失的回归结果
上面的图的分位数回归的代码在这里。
理解分位数损失
基于分位数的回归旨在估计给定一定预测变量值的响应变量的条件“分位数”。分位数损失实际上只是MAE的延伸(当分位数是50%时,它就是MAE)。
我们的想法是,根据我们想给正误差或负误差更多的值来选择分位数值。损失函数试图对于过高的估计和过低的估计不同的惩罚,在此基础上选择分位数(γ)。例如,γ= 0.25分位数损失函数对于过高的预测给出了更多的惩罚,试图保持预测值略低于中位数。
![187220c2fac5ac74975dbf901edccc2b.png](https://i-blog.csdnimg.cn/blog_migrate/d8542b766ebc8b785918d59185542c2c.jpeg)
γ是所需的分位数和值在0和1之间。
![9f994d88f5d289eef95647d458705d2a.png](https://i-blog.csdnimg.cn/blog_migrate/428ce7260e515419a001d0bd8928dac2.jpeg)
Plot of Quantile Loss (Y-axis) vs. Predictions (X-axis). True value of Y = 0
我们也可以使用这个损失函数来计算神经网络或基于树的模型中的预测区间。下面是梯度增强树回归的Sklearn实现示例。
![10c6e628d91ea2782a1471fe6b0ea753.png](https://i-blog.csdnimg.cn/blog_migrate/d41d6bdee033ddd5840105fe6140e19b.jpeg)
使用分位数损失预测间隔(梯度提升回归器)
上图显示了使用sklearn库的GradientBoostingRegression中可用的分位数损失函数计算出的90%的预测区间。上限是γ= 0.95,下限γ= 0.05。