4.2.1 损失函数和正则化
笔者初学机器学习时曾被同事问倒:“机器学习仅通过损失函数加一个正则项就能进行学习,那它的原理是什么?”
让我们回顾一下1.2.2节的机器学习的基础理论。已知机器学习的一种学习范式是权衡经验风险和结构风险,第1章的式(1-2)是为了方便描述的一种简化写法,表明了损失和正则构成了机器学习的目标。现在我们将学习器学到的映射f以W参数表示,模型的复杂度也表示为W的函数。学习f即是学习f中的参数W,如式4-1所示。
第一项为损失函数L的平均,第二项为正则项,用于实现正则化(Regularization)。我们称S(W)为目标函数,机器学习中的优化求解算法(比如梯度下降等)即是求解令S最小的W,式(4-1)中损失函数为单实例损失求和后的平均,每个实例对整体损失产生贡献。
式(4-1)是一种常见和直观的写法,理论上来说,最终的损失由损失函数L和其聚合方式共同决定,例如此处聚合为均值,理论上也可以聚合最大值或其他统计量。另外,当上下文将损失函数和代价函数区分开来时,区别如下所示。
·损失函数(Loss Function):单个样本上损失计算函数。
·代价函数(Cost Function):整个训练集上的损失的聚合。
·目标函数(Object Function):最终优化的函数,即代价函数和正则化项。
大量的机器学习算法基于上述范式学习。那什么是损失函数呢?
损失函数是一种评估算法对训练数据集拟合好坏程度的方法,是一种类似距离的度量方法,它必须反映实际情况或表达经验,其值非负,一般值越大表明拟合效果越差。例如,如果预测完全错误,那么损失函数值将很大,反之损失函数值很小。按照这个思路,我们试着先写出误差函数。
设(x,y)为向量x对应的y,同时假设机器学习获得了一个分类器的模型F,F的输入为向量x,输出为y'。则可以很自然地定义式(4-2)所示的误差函数。该误差函数的含义很明显,即当预测值等于真实值时,误差为0,否则为1。
式(4-2)表示的是单个样例的损失,对于整个样本集的误差可表示为式(4-3)。
如果式(4-3)的值很小或为0,则表示分类模型F的经验误差风险很小,而值很大则表示经验误差风险很大。机器学习的目标就是在指定的假设空间F中寻找合适的参数ω,使得式(4-3)达到最小——最小化经验风险。这是一个优化问题,但由于上述表达式不连续、不可导,所以在数学上并不方便优化求解。
转换问题的求解思路:如能找到一个与上述问题有关的,且数学性质好,便于求解的函数,那么该问题便迎刃而解。损失函数就是解决该问题的关键,例如要求损失函数具有良好的数学性质,比如连续、可导、凸性等,是待求解问题的上界等,当样本量趋于无穷时两者能达到一致性,如此通过优化损失函数就能间接求解原问题,此时损失函数就是针对原目标的数学模型,是对现实世界的建模,也是真实问题的代理。正因为此,可以说损失函数是现今机器学习的基础,是连接理论与实践的桥梁。
不同的损失函数关注了现实问题的不同方面,例如有的损失函数具有对称性(正负误差对称),而有的损失函数更关注某一类误差,有的关注整体效果,有的关注排序。实践中除了关注数学性质外,可能还需关注损失函数的计算成本、对异常值是否敏感等。这些问题涉及损失函数如何设计,感兴趣的读者可自行查找相关资料。式(4-2)实际就是0-1损失,下面列出了几种常见的损失函数(这里不区分损失函数和成本函数)。
1.线性回归损失
线性回归中常用的损失函数有:平方损失和平均绝对损失。实际应用中分别为均方误差(Mean Squared Error,MSE)和平均绝对误差(Mean Absolute Error,MAE),又称L2和L1损失。
MSE表示预测值与目标值之差的平方和,基于欧式距离,计算简单且具有凸性,常应用于最小二乘法中。定义如式(4-4)所示。
MAE表示预测值与目标值之差的绝对值,该函数导数不连续。定义如(4-5)所示。
Python代码示例:
def mse(yi, fi): return np.sum((yi - fi)**2) def mae(yi, fi): return np.sum(np.abs(yi - fi))/yi.size
MSE随着误差的增加,损会失以平方指数增加,而MAE则为线性增加。当数据集中存在较多异常值时,MSE会导致模型的整体性能下降,MAE则更为平稳,对异常值的鲁棒性更好;一般情况下,在数据分析和处理阶段会对异常值进行处理,此时MSE是更好的选择。为了避免MAE和MSE的缺点,我们有改进版本的Huber损失函数,其定义如式(4-6)所示。
其Python实现如下:
def Huber(yi, fi, delta=2.): return np.where(np.abs(yi-fi) < delta,.5*(yi-fi)**2 , delta*(np.abs(yi-fi)-0.5*delta))
三者图形示例如图4-7所示。
图4-7 MSE、MAE、Huber损失函数曲线
下面看看常用的二分类中的损失函数。
2.Hinge损失函数
Hinge常见于支持向量机中。当预测值和真实值乘积大于1时,损失为0,否则为线性损失。其定义如(4-7)所示。
其Python实现为:
def Hinge(yi, fi): return np.max(0, 1 - fi * yi)
Hinge是0-1误差的上界,如图4-8所示。
3.指数损失
指数损失定义如式(4-8)所示,为连续可导凸函数,数学性质非常好,常见于AdaBoost算法中。当预测值和真实值类别标号不一致时对学习的惩罚力度非常大(指数力度),否则,符号一致且乘积较大时,惩罚非常小。
其Python实现为:
def eloss(yi, fi): return np.e**(-yi*fi)
其曲线如图4-9所示。
图4-8 Hinge损失函数曲线
图4-9 指数损失函数曲线
4.交叉熵损失
交叉熵损失函数定义如式(4-9)所示,又称对数损失,该函数为连续可导凸函数,数学性质非常好,常见于逻辑回归中。在正标签下,当预测概率接近1时惩罚几乎为0;但当预测概率趋向于0时,惩罚非常大。负标签情况类似,曲线对称。
其Python实现为:
def CrossEntropy(yi, fi): if yi == 1: return -np.log(fi) else: return -np.log(1 - fi)
其曲线如图4-10所示。
图4-10 交叉熵损失函数曲线
sklearn.metrics包中实现了很多评价指标,其中就包括常用损失函数,例如0-1损失对应zero_one_loss,hinge损失对应hinge_loss。详情请参考:https://scikit-learn.org/stable/modules/classes.html#module-sklearn.metrics。
5.正则化
从第1章可知,正则损失最小化是机器学习范式的一种实现,正则项作为算法的“稳定剂”,起到了惩罚和控制模型的复杂度的作用,是防止过拟合的经典方法,也符合奥卡姆剃刀原则。
不同的学习算法的模型复杂度可以用不同的方式来衡量,此处统一将这种衡量方式以“正则化”这一概念表述。正则化项为了表征模型复杂度,要求正则化的值随模型复杂度增大而增大,这样才能在最小化优化过程中起到惩罚的作用。下面列举了几个常见模型的正则项。
1)回归模型:回归模型中的正则项如图4-11所示。其中,L1范数的惩罚项又称为Lasso回归(一般翻译为套索回归),其值为各项系数绝对值的和;L2范数的惩罚项又称为Ridge回归(一般翻译为岭回归),其值为各项系数平方的和;ElasticNet直译为弹性网络,是L1和L2的线性组合。回归模型中变量越多、模型越复杂,明显可见L1、L2的值也有越大的倾向。
图4-11 回归模型中的正则项
实际上L1、L2和上述的损失函数式(4-4)、式(4-5)的数学含义是一致的,以致有L1、L2损失函数的说法。
2)在决策树模型中,以叶子结点个数∣T∣作为正则项时也直观表征了叶子结点越多模型越复杂的特性。
3)XGBoost[1]中正则项如式(4-10)所示,T指叶子结点的数量,ω指叶子结点的得分值,前面的系数调节两者权重,其值也表征了模型越复杂其值也越大的特性。
从数学角度看上述的正则项,是多维向量到低维的一种映射。
注意:不同的正则项,其优化求解算法和计算效率也不相同,实践中注意结合样本量权衡。例如sklearn的逻辑回归中L1使用坐标下降算法(Coordinate Descent),L2则有多种选择:lbfgs、sag和newton-cg,分别对应拟牛顿(Quasi-Newton)、随机平均梯度下降(Stochastic Average Gradient descent)和牛顿法,而ElasticNet使用随机梯度下降法(Stochastic Gradient Descent)。而对于大数据集(样本量大和特征多)来说,随机梯度分类和回归器效率更高(SGDClassifier和SGDRegressor)。
[1] https://arxiv.org/pdf/1603.02754.pdf