本系列是《玩转机器学习教程》一个整理的视频笔记。本小节通过探讨模型过拟合的现象,提出岭回归这个模型正则化方式,最后通过实验对α取值与过拟合(拟合曲线)之间的关系进行探讨,随着α取值从小到大,拟合曲线从弯弯曲曲到逐渐平滑。
1
引入模型正则化
上一小节提到了解决模型过拟合也就是方差误差的5种手段,尤其是最后一种非常标准的处理手段~模型正则化。
模型正则化的英文为Regularization。那什么是模型正则化呢?可以看上图中的拟合曲线,这是之前使用多项式回归过拟合样本数据的一个例子,此时观察这个拟合曲线非常的弯曲陡峭,尤其在两边的位置弯曲陡峭程度非常的大。在初中数学中学过多项式曲线的数学公式,其中每一个多项式项前面都会有一个系数θ。
对于上图针对数据样本过拟合的多项式曲线,很显然前面的系数中有一些系数会非常的大(因为此时的拟合曲线弯曲陡峭程度比较高),而模型正则化所要做的事情就是希望能够限制这些系数的大小。
这里先简单的来验证一下,发生过拟合的多项式拟合曲线其中的某些系数θ值是不是非常大。
- Part1:使用具有一个特征且与y呈现二次关系的虚拟数据集。
- Part2:使用Pipeline管道的方式创建多项式回归,为了让过拟合的效果更加明显,将degree值设置为100,使用100阶的多项式来拟合数据。
- Part3:绘制degree为100的多项式拟合曲线。
- Part4:调用coef_属性查看100阶多项式的系数。
lin_reg.coef_
其实这就是过拟合的效果,由于为了能够尽量减少和样本数据之间的误差,拟合曲线变的非常的陡峭,对应的数学表示其实就是多项式方程相应的系数非常大。
模型正则化是以怎样的思路来解决过拟合的问题呢???
对于多项式回归来说,求得最优解的目标就是使得式一目标函数作为损失函数尽可能的小,之前也介绍过如求式一目标函数的最小值,其实相当于求MSE损失函数(原始y和使用θ预测的y_hat之间的误差尽可能小)。
如果发生过拟合的话,这个θ系数就会非常的大,那么要如何进行限制才能使θ系数不会太大。当然就是改变一下损失函数,将损失函数改为式三,其中J(θ)和之前损失函数MSE一样,不同之处在后面多添加了一项,这一项是所有θi的平方和,如果将后面多添加的这一项尽可能的小,其实相当于让每一个θ系数都尽可能的小。通过这样的方式,在最小化J(θ)MSE的同时,让所有的系数θ都尽可能的小,这样就不会出现之前过拟合中每一个系数都特别大的现象(反映在拟合曲线上就是非常弯曲陡峭),这就是模型正则化的基本原理。这里还有几个小细节需要注意。
- 通过式三可以观察到多添加的那一项θi中的i是从1到n,也就是说不需要将θ0进行正则化,这是因为θ0本身不是任何一个多项式项的系数,θ0只是一个截距,θ0截距决定了整个曲线的高低,但是不能够决定曲线每部分的陡峭以及缓和程度,所以我们在模型正则化的时候不需要加上θ0;
- 通过式三可以观察到多添加的那一项有一个1/2,这其实是一个惯例,习惯问题,这个1/2加不加都可以。在求解线性回归的时候使用梯度下降法,需要对损失函数求导,而添加的一项中每一个θi都有一个平方,进行求导的话变成了2倍θi,此时1/2会和求导出来的2合在一起约掉,这仅仅是方便计算而已,因此要不要这个1/2都是可以的;
- 通过式三可以观察到多添加的那一项有α,α是一个新的超参数。模型正则化就是让这些θ系数尽可能的小,而α代表的就是这些θ系数小的程度占整个优化损失函数的程度是多小?
- 在极端情况下,α值等于0的时候,相当于并没有添加正则化项,此时损失函数仅仅包含MSE;
- 在极端情况下,α值等于正无穷的时候,当然在计算机的表示中没有正无穷这个概念的,可以想象成是一个非常非常大的数,那么此时前面的MSE所占整个式三的比重就会变得非常非常的小。主要的优化任务就变成了,让每一个θi系数都尽可能的小,这种情况下,所有的θi都等于0的时候才能使得θi的平方尽可能的小。
当然对于MSE(预测的准确度)和正则化项(让每个θ系数都尽量小)之间取得一个平衡,那么对于不同的数据我们需要对α尝试不同的取值。当然在这一小节会通过具体的编程来让大家看到不同的α取值带来的不同影响,也由于有了这个α,所以alpha2就是一个常数,也正是因为如此,这个12加不加都没有关系,相当于把这部分12和α融合在了一起。
2
模型正则化之岭回归
实际上模型正则化的方式不仅有上面的一种,还有其他的模型正则化方式。本小节将损失函数加入α乘以θi平方这种模型正则化的方式称之为岭回归,这里的岭是山岭的意思。
在这章的最后一个小节会比较两种不同模型正则化的方式,那个时候就会对为什么叫做岭回归有更深刻的认识。为了让大家对模型正则化背后的原理有所了解,下面使用实际的编程来看一看使用了这种岭回归的模型正则化方式限制每一个θ系数大小最终的效果是怎样的。
- Part1:首先生成一组测试用例,这组测试用例的x是在-3.0到3.0之间均匀取值的100个样本,每个样本只有一个特征,相应的y值与x呈现包含一定噪声的线性关系。
- Part2:使用多项式回归的方式对生成的测试用例进行预测,求出相应的均方误差值,并绘制拟合曲线。
绘制多项式回归阶数为20的拟合曲线。
通过均方误差的结果以及拟合曲线可以看出模型显然发生了过拟合,通过拟合曲线可以看出在两端拟合曲线非常的弯曲。在这种极端情况下,虽然模型在所有训练数据上的均方误差能够达到最小,但是可以想象一下如果来了一个新的数据,这根拟合曲线对新数据的预测结果肯定是不准确的。
为了方便后续的实验,将前面绘制代码进行简单的封装,将封装后的函数称为plot_model,当传入一个经过fit训练好的model之后,就会绘制出model的拟合曲线。
这个封装的plot_model函数和前面绘制代码在逻辑上是一样的,根据模型绘制出X_plot相应的曲线。为了验证封装绘制函数plot_model,将前面训练好的多项式回归对象plot_reg传入进去。
代码语言:javascript复制plot_model(poly_reg)
可以发现封装前和封装后得到的拟合图像是一样的。
- Part3:使用岭回归的方式对生成的测试用例进行预测,求出相应的均方误差值,并绘制拟合曲线。
由于时间关系岭回归的底层实现在这个课程中不进行实现,这个课程的目的是让我们能够更加深入的理解这些机器学习算法背后的原理。实际上我们自己实现的底层代码相较于sklearn为我们封装的方法来说比较简陋,sklearn封装的机器学习算法更加精度以及可靠。对于岭回归而言,sklearn将岭回归封装在linear_model包下Ridge类,创建岭回归和其他机器学习模型的创建一样,对于岭回归来说,需要传入模型正则化的比重α值。
代码语言:javascript复制from sklearn.linear_model import Ridge
ridge = Ridge(alpha = 1) # 将alpha的值设置为1
为了调用岭回归,依然使用创建多项式回归时候的管道。类比于多项式回归的创建,将PolynomialRegression改写成RidgeRegression。
此时的RidgeRegression函数有两个参数,一个是degree多项式的阶数,另一个参数就是确定模型正则化比重的α值。上面封装好了岭回归的过程,接下来就可以试验岭回归的效果了,在这里需要试验几组不同的α的值,看看alpha值大小对模型过拟合的影响,这里为了试验的规范性将degree阶数统一设置为20。
- Step1:岭回归超参数α取较小值0.0001。
对于岭回归来说,由于损失函数中新添加的一项是所有θ系数平方和,之前通过实验观察到,对于多项式回归来说得到的这些θ值都非常的大,有的θ值甚至达到了10的几十次方这样的级别,所以为了能够限制让这些θ值变的比较小,将α值设置为0.0001,其实还可以将α的取值设置的更小一些。
此时得到均方误差值为1.32,比前面使用线性回归得到的均方误差167.94好太多了,这就是模型正则化的威力,模型正则化能够让整个模型泛化能力得到大大的提高,而模型正则化的原理其实就是因为对于过拟合而言,多项式项前面的系数θ值太大了,在原来MSE损失函数的基础上加上了正则化项让这些θ系数值减小。
接下里就可以使用封装的plot_model函数绘制一下拟合曲线。
代码语言:javascript复制plot_model(ridge1_reg)
观察两次拟合曲线。
相比于不使用岭回归的拟合曲线,使用岭回归的拟合曲线要平缓的多。
此时得到的均方误差值为1.18,比刚才α值设置为0.0001时候又好了一些。
接下里就可以使用封装的plot_model函数绘制一下拟合曲线。
代码语言:javascript复制plot_model(ridge2_reg)
观察三次拟合曲线。
当α为1时候的拟合曲线比前面的两个拟合曲线又平滑了很多。创建的测试用例其实本身就是一根倾斜的直线,可以观察α为1时候的拟合曲线,此时很接近那条倾斜的直线。
此时得到的均方误差是1.3,依然是比较小,但是相比于之前α的取值稍微有点上升。出现这种情况,有可能是正则化有一点过头了。
接下里就可以使用封装的plot_model函数绘制一下拟合曲线。
代码语言:javascript复制plot_model(ridge3_reg)
观察四次拟合曲线。
此时得到的拟合曲线已经相当平滑了,少了很多弯曲的波动,比起上面的曲线更加平滑。
此时得到的均方误差更大了一些,但是依然比之前过拟合的情况要好很多。
接下里就可以使用封装的plot_model函数绘制一下拟合曲线。
代码语言:javascript复制plot_model(ridge4_reg)
绘制出来的拟合曲线机不是一根平的直线。在之前岭回归对应的那个损失函数中,如果α值非常大的时候,本质就是在优化我们模型正则化那一项,也就是说让所有θi的平方和尽量的小,θ最小值的情况就是都等于0的情况,最终的结果就是这样一根和x轴平行的直线,此时曲线完全没有了弯曲没有了坡度。
使用岭回归这种方式的时候,引入了一个新的超参数α。当对于不同的数据,使用不同模型的时候,也需要对α这个超参数进行一定的寻找。这一小节展示了不同的α取值,得到最终的效果是怎样的。
通过上图也可以发现,随着α值从小到大,曲线从弯弯曲曲到逐渐平滑,直至最后变成了一根完全平整的直线。当然最终的结果也不是我们想要的,我们需要的是是整个模型泛化能力达到最佳的中间某个状态。
下一小节会介绍另一种模型正则化的方法~LASSO回归。