Python机器学习核心算法编程实例
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.6 缩减法

如果数据的特征比样本点还多应该怎么办呢?是否还可以使用线性回归和之前的方法来做预测?答案是否定的,即不能再使用前面介绍的方法。这是因为在计算的时候会出错。

如果特征比样本点还多,则说明输入数据的矩阵不是满秩矩阵。非满秩矩阵在求逆时会出现许多难测的情况。

为了解决这个问题,统计学家引入了岭回归的概念,这就是本节将介绍的第一种缩减法。接着是lasso回归,该方法效果很好,但计算复杂。本节最后介绍前向逐步线性回归,可以得到与lasso差不多的效果,并且更容易实现。

2.6.1 岭回归

简单说来,岭回归就是在矩阵上加一个,从而使得矩阵非奇异,进而能对求逆。其中,矩阵为一个的单位矩阵(即对角线上元素全为1,其他元素全为0),而是一个用户定义的数值。在这种情况下,回归系数的计算公式将变成:

岭回归最先用来处理特征数多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计。此处通过引入来限制所有之和,通过引入该惩罚项,能够减少不重要的参数,这个技术在统计学中也叫作缩减(shrinkage)。

说明:岭回归中的岭是什么呢?岭回归使用了单位矩阵乘以常量,观察其中的单位矩阵,可以看到值1贯穿整个对角线,其余元素全是0。形象地讲,在0构成的平面上有一条1组成的“岭”,这就是岭回归中“岭”的由来。

缩减法可以去掉不重要的参数,使人们能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果。

【例2-8岭回归分析数据实例。

以上代码中包含了两个函数:函数ridgeRegres()用于计算回归系数,而函数ridgeTest()用于在一组上测试结果。

第一个函数ridgeRegres()实现了给定lambda下的岭回归求解。如果没指定lambda,则默认为0.2。由于lambda是Python保留的关键字,因此程序中使用了lam来代替。该函数首先构建矩阵,然后用lam乘以单位矩阵(可调用NumPy库中的方法eye()来生成)。在普通回归方法可能会产生错误时,岭回归仍可以正常工作。是不是就不再需要检查行列式是否为零了,对吗?不完全对,当lambda设定为0的时候一样可能产生错误,所以这里仍需要做一个检查。最后,如果矩阵非奇异则计算回归系数并返回。

为了使用岭回归和缩减技术,首先需要对特征做标准化处理。以上代码中的ridgeTest()函数就展示了数据标准化的过程。

处理完成后就可以在30个不同lambda下调用ridgeRegres()函数。注意,这里的lambda应以指数级变化,这样可以看出lambda在分别取非常小的值和非常大的值时对结果造成的影响。最后将所有的回归系数输出到一个矩阵并返回。

【例2-9利用岭回归对给定数据进行预测。

运行程序,输出如下:

2.6.2 lasso回归

不难证明,在增加如下约束时,普通最小二乘法回归会得到与岭回归一样的公式:

上式限定了所有回归系数的平方和不能大于。使用普通最小二乘法回归时,若两个或更多的特征相关,可能得出一个很大的正系数和一个很大的负系数。正是由于上述限制条件的存在,使用岭回归可以避免这个问题。

与岭回归类似,另一种缩减方法lasso也对回归系数做了限定,对应的约束条件为

唯一不同点在于,这个约束条件使用绝对值取代了平方和。虽然约束形式只是稍加变化,结果却大相径庭:在足够小的时候,一些系数会因此被迫缩减到0,这个特性可以帮助我们更好地理解数据。这两个约束条件在公式上看起来相差无几,但细微的变化却极大地增加了计算复杂度(为了在这个新的约束条件下解出回归系数,需要使用二次规划算法)。

2.6.3 前向逐步线性回归

前向逐步线性回归算法可以得到与lasso回归差不多的效果,但更加简单。它属于一种贪心算法,即每一步都尽可能减小误差。一开始,所有的权重都设为1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。

该算法的伪代码为:

【例2-10利用前向逐步线性回归对数据进行分析处理。