zl程序教程

您现在的位置是:首页 >  其他

当前栏目

预测分析:R语言实现2.7 正则化

2023-03-09 22:22:24 时间

2.7 正则化


变量选择是一个重要的过程,因为它试图通过去除与输出无关的变量,让模型解释更简单、训练更容易,并且没有虚假的关联。这是处理过拟合问题的一种可能的方法。总体而言,我们并不期望一个模型能完全拟合训练数据。实际上,过拟合问题通常意味着,如果过分拟合训练数据,对我们在未知数据上的预测模型精确度反而是有害的。在关于正则化(regularization)的这一节,我们要学习一种减少变量数以处理过拟合的替代方法。正则化实质上是在训练程序中引入刻意的偏误或约束条件,以此防止系数取值过大的一个过程。因为这是一个尝试缩小系数的过程,所以我们要观察的这种方法也称为收缩方法(shrinkage method)。

2.7.1 岭回归

当参数的数量非常大的时候,尤其是和能获得的观测数据的数量相比很大时,线性回归往往会表现出非常高的方差。这也就是说,在一些观测数据中的微小变化会导致系数的显著变化。岭回归(ridge regression)是一种通过其约束条件引入偏误但能有效地减小模型的方差的方法。岭回归试图把残差平方和(RSS)加上系数的平方和乘以一个用希腊字母表示的常数构成的项(∑2)的累加和最小化。对于一个带有k个参数的模型(不包括常数项0)以及带有n条观测数据的数据集,岭回归会使下列数量最小化:

 

在这里,我们还是想把RSS最小化,但第二个项是惩罚项,当任何系数很大时它也会很大。因此,在最小化的时候,我们就会有效地把系数压缩到更小的值。参数被称为元参数(meta parameter),它是我们需要选择或调优的。一个非常大的值会掩盖RSS项并把系数压缩到0。过小的值对于过拟合就没什么效果,而一个等于0的参数则只是进行普通的线性回归。

当进行岭回归时,经常需要通过把所有特征值除以它们的方差来进行比例缩放。这对于普通线性回归不适用,因为如果某个特征用一个等于10的因子进行缩放,那么系数也会被一个等于1/10的因子进行缩放来补偿。在岭回归里,特征的缩放则是通过惩罚项来影响所有其他特征的计算的。

2.7.2 最小绝对值收缩和选择算子

最小绝对值收缩和选择算子(lasso)是岭回归的一种替代正则化方法。它们之间的差别只是体现在惩罚项里,它最小化的是系数的绝对值之和。

 

其实,惩罚项里的这个差别是非常显著的,由于lasso会把某些系数完全收缩到0,所以它兼具了收缩和选择的功能,而这对于岭回归是不具备的。即便如此,在这两种模型之间并没有明确的赢家。依赖于输入特征的某个子集的模型往往用lasso表现更好;很多不同变量的系数具有较大分散度的模型则往往在岭回归下有更好的表现。两者通常都是值得尝试的。

岭回归里的惩罚项经常被称为l2惩罚项,而lasso里的惩罚项被称为l1惩罚项。这是来自向量的范数(norm)的数学概念。向量的范数是一个函数,它会给该向量分配一个代表其长度或大小的正数。l1和l2范数都是一类被称为p范数(p-norm)的范数

中的范例,对于具有n个分量的向量v,p范数具有下面的一般形式:

2.7.3 在R语言里实现正则化

有很多不同的函数和扩展包都实现了岭回归,例如MASS包里的lm.ridge()函数和genridge包里的ridge()函数。对于lasso来说,也有lars包可用。在本章,我们会采用来自glmnet包的glmnet()函数,这是因为它具有一致且友好的接口。正则化处理的关键是确定采用一个适当的值。glmnet()函数采用的方法是利用一组不同的值,并针对每个值训练一个回归模型。然后,你既可以手工挑出一个值,也可以利用某个技术来估算最佳的值。我们可以通过lambda参数指定要尝试的值序列;否则,函数会采用默认的100个值的序列。给glmnet()函数的第一个参数必须是一个特征矩阵,它可以利用model.matrix()函数来构建。

第二个参数是一个带有输出变量的向量。最后,alpha参数是岭回归(参数取值为0)和lasso(参数取值为1)之间的切换开关。我们现在准备用二手车数据集来训练一些模型:

 

因为提供了250个值的序列,所以我们实际上训练了250个岭回归模型和另外250个lasso模型。可以对第100个模型来查看glmnet()函数产生的对象的lambda属性里的值,并对该对象调用coef()函数来获得对应的系数,如下所示:

 

也可以调用plot()函数来获得一个绘图,显示系数的值是如何随着值的对数变化而变化的。把岭回归和 lasso 的对应绘图并排显示是非常有帮助的:

 

这两幅图的关键差异在于,lasso会强制把很多系数减小到正好为0,而在岭回归里,系数往往是平滑地减小,只有当取极端值时才会全部一起变为0。这个规律可以进一步从两幅图的上部水平轴上的数值看出来,它显示的是当取不同值时非零系数的个数。从这个意义上说,lasso在两个方面具有明显优势:它经常可以用来进行特征选择(因为系数为0的特征实际上是不包含在模型中的),以及为了把过拟合问题最小化而进行正则化。我们可以通过改变赋予xvar参数的值来获得其他有用的绘图。它取值为norm时会在x轴绘制系数的l1范数,取值为dev时则会绘制该模型所解释的偏差(deviance)的百分比。我们会在下一章学习有关偏差的内容。

 

为了处理给找到一个合适值的问题,glmnet包提供了cv.glmnet()函数。它对训练数据运用了一种称为交叉验证(cross-validation)的技术(我们会在第5章中学习到它),从而找到能够最小化均方差(MSE)的合适的值。

 

如果我们绘制cv.glmnet()函数产生的结果,可以看到MSE是如何随着的不同取值而变化的:

 

每个点上下的竖条是为每个的绘制值而显示的MSE估计值上下的标准差的误差条。绘图还显示了两条垂直的虚线。第一条垂直线对应的是lambda.min的值,它是交叉验证提出的优化值。右侧的第二条垂直线是lambda.1se属性的值。它对应了距离lambda. min一个标准误(standard error)的值,并产生了一个更为正则化的模型。

在glmnet包里也有一个predict()函数,它现在可以在多种不同的背景下执行。例如,可以针对某个不在原始清单里的值求得模型的系数。例如,进行如下操作:

 

注意,貌似lasso在这个示例中并没有把任何系数强制为0,这说明根据MSE的情况,不建议去除二手车数据集里的任何系数。最后,我们可以再次调用predict()函数,通过newx参数为要进行预测的观测数据提供一个特征矩阵,从而用一个正则化的模型来作出预测:

 

在测试数据上,lasso模型的效果最好,且略好于普通模型,而不像岭回归在这个示例中的表现那么不理想。