正则化的具体知识看我这篇博客我们知道正则化的本质是通过约束模型的权重来实现的,而具体对模型权重进行约束的实现方法有岭回归、套索回归和弹性网络。下面对其一一进行介绍。
岭回归(吉洪洛夫正则化)是线性回归的正则化版:在成本函数中添加一个 α ∑ i = n n θ i 2 \alpha\sum_{i=n}^n \theta_i^2 α∑i=nnθi2(这个项要规定小于一个实数C)的正则项。加上正则项后学习算法就从原来的只需要拟合数据变成了拟合数据的同时也要控制 α ∑ i = n n θ i 2 < C \alpha\sum_{i=n}^n \theta_i^2
α∑i=nnθi2<C ,这样就能控制权重保存最小。同时我们也要注意一个点,正则化只能在训练的时候添加的成本函数中,用于在训练集上出现过拟合问题,一旦训练完成评估模型指标的时候就需要使用未经正则化的性能指标来评估模型性能。然后这个正则化项中的 α \alpha α是一个参数(需要人每次手动指定的参数),它的作用就是控制模型进行正则化的程度。如果 α = 0 \alpha=0 α=0,正则化失效就变成了普通的岭回归,相反如果 α \alpha α很大的话就需要将所有的权重参数控制到很小,这时候的结果是一条穿过数据平局值的水平线。
J ( θ ) = M S E ( θ ) + α 1 2 ∑ i = 1 n θ i 2 J(\theta)=MSE(\theta)+\alpha \frac 1 2 \sum_{i=1}^n \theta_i ^2 J(θ)=MSE(θ)+α21i=1∑nθi2
岭回归对输入特征的大小非常敏感,所以在使用其之前需要对数据进行缩放即标准化
我们知道机器学习的本质就求解使得模型误差最小的模型参数组合的过程,而求解方法通常分为两种,一种是闭式解方程(直接一步通过公式求出最优的模型参数)另一种就是梯度下降(使用迭代的方法求出最优参数)
A为一个n*n的单位矩阵
下面是Scikit-learn执行闭式解的岭回归
1.1 首先创建数据集
m=100
X=6*np.random.rand(m,1)-3
y=0.5*X**2+X+2+np.random.randn(m,1)
plt.scatter(X,y)
1.2 使用岭回归对数据进行拟合
from sklearn.linear_model import Ridge
ridge_reg=Ridge(alpha=1,solver="cholesky")
ridge_reg.fit(X,y)
ridge_reg.predict([[1.5]])
from sklearn.linear_model import SGDRegressor
sgd_reg=SGDRegressor(penalty="l2")#采用l2正则化
sgd_reg.fit(X,y.ravel())#y是多维的这里消除y的维
sgd_reg.predict([[1.5]])
预测结果
Ridge回归在不抛弃任何一个变量的情况下,缩小了回归系数,使得模型相对而言比较的稳定,但这会使得模型的变量特别多,模型解释性差。有没有折中一点的办法呢?即又可以防止过拟合,同时克服Ridge回归模型变量多的缺点呢?有,这就是下面说的Lasso回归
Lasso回归是线性回归的另一种正则化,叫做最小绝对搜索和选择算子回归(Least Absolute Shrinkage and Selection Operator Regression),与岭回归一样,它也是向成本函数中增加一个正则项,但不同的是岭回归使用的是L2正则化而Lasso回归使用的是L1正则化。
J ( θ ) = M S E ( θ ) + α ∑ i = 1 n ∣ θ i ∣ J(\theta)=MSE(\theta)+\alpha\sum_{i=1}^n|\theta_i| J(θ)=MSE(θ)+αi=1∑n∣θi∣
Lasso回归的一个重要特点就是它倾向于完全消除掉不重要的特征的权重(也就是将它们设置为0),所以Lasson回归首先会自动执行特征选择对特征矩阵进行处理最后输出一个稀疏矩阵(即只有很少的特征有非零权重)
如下图,是Lasso回归和Ridge回归的一个梯度下降迭代路线图(椭圆的是没有使用正则化,菱形是使用了L1正则化,圆形是使用了L2正则化)
从Lasso回归的公式中可以看出,由于加入的是L1正则化项,引入了绝对值,这就是Lasso回归有一个很大的问题,就是由于L1正则化项用的是绝对值之和,导致损失函数有不可导的点,也就是说Lasso回归是不可微的,但是如果我们使用次梯度向量g作为代替,依旧可以让梯度下降正常运作。
次梯度法(subgradient method)是传统梯度下降方法的拓展,用来处理不可微(non-differentiable )的凸函数。它的优势是比传统方法处理问题范围大,但劣势是算法收敛速度慢。而传统的梯度下降方法只能处理可导函数。 我们可以通俗的把次梯度理解为把不可微的点上的次梯度向量想象为这个点周围的梯度向量之间的中间矢量。
g ( θ , J ) = ∇ θ M S E ( θ ) = ( s i g n ( θ 1 ) s i g n ( θ 2 ) . . s i g n ( θ n ) ) g(\theta,J)=\nabla_\theta{MSE}(\theta)=\begin{pmatrix} sign(\theta_1)\\ sign(\theta_2) \\ .\\ .\\ sign(\theta_n) \\ \end{pmatrix} g(θ,J)=∇θMSE(θ)=⎝ ⎛sign(θ1)sign(θ2)..sign(θn)⎠ ⎞
sign就是我们所熟悉的符号函数
from sklearn.linear_model import Lasso
lasso_reg=Lasso(alpha=0.1)
lasso_reg.fit(X,y)
lasso_reg.predict([[1.5]])
弹性网络上岭回归与Lasso回归之间的中间地带,其正则项就是岭回归和Lasso回归的正则项的混合,混合比例通过r来控制,当r=0时,弹性网络就是岭回归,当r=1时相当于Lasso回归,所以理解起来还是比较简单。
J ( θ ) = M S E ( θ ) + r α ∑ i = 1 n ∣ θ i ∣ + 1 − r 2 α ∑ i = 1 n θ i 2 J(\theta)=MSE(\theta)+r\alpha\sum_{i=1}^n|\theta_i|+ \frac {1-r} 2 \alpha\sum_{i=1}^n \theta_i ^2 J(θ)=MSE(θ)+rαi=1∑n∣θi∣+21−rαi=1∑nθi2
from sklearn.linear_model import ElasticNet
elastic_net=ElasticNet(alpha=0.1,l1_ratio=0.5)
elastic_net.fit(X,y)
elastic_net.predict([[1.5]])
上面介绍了三种对模型权重(参数)进行约束的方法,那么我们在实际操作中应该如何进行选择,通常来说有正则化哪怕说很小总会比没有好一些。所以大多是情况下,我们应该避免使用没有正则化的线性回归。岭回归可以作为我们的默认选择,如果没有特殊要求我们可以使用岭回归,但是如果你觉得实际用到的特征比较少(有很多没有用的特征)时我们可以更倾向于Lasso回归或弹性网络,因为它们都会将无用特征的权重降为0,一般来说弹性网络的性能会优于Lasso回归,因为当特征数量超过训练实例数量,又或者是几个特征强相关时,Lasso回归可能会很不稳定。