回归模型-3Lasso 回归

 

3 Lasso 回归

看模型的范式 Lasso 回归
问题是什么 回归拟合
模型是什么 线性模型
优化指标 最小二乘损失的基础上+ L1 正则化项
求解方法 坐标下降法
评价模型  

首先,lasso与岭回归都是正则化目标函数。但是,与岭回归不同,Lasso 使用L1正则化,这会带来特征选择的特性——将不重要特征的系数压缩至零,也就是生成稀疏解。 Lasso 在最小二乘损失的基础上添加 L1 正则化项(系数绝对值之和),其目标函数为: \(\begin{matrix}\text{Q=}&\min_\beta\left\{\|\mathbf{y}-\mathbf{X}\boldsymbol{\beta}\|_2^2+\lambda\|\boldsymbol{\beta}\|_1\right\}\end{matrix}\)

其中$λ$>0是正则化参数,$|\beta|1=\sum{j=1}^p \beta_j $是L1正则化项。我们的目标是求解参数向量$β$,使得$Q$的值最小。
由于L1正则项 $∥β∥1=\sum{j=1}^{n} \beta_j $ 不可导,故不能用常规求矩阵偏导的方式来计算$β$向量,一般采用坐标下降法。在固定其他参数的情况下,对每个系数$β_j$依次优化。具体方法如下:
  • 令 $\mathbf{r}^{(j)}=\mathbf{y}-\sum_{k\neq j}\mathbf{x}_k\beta_k$ 其中 $\mathbf{x}_j$ 是数据矩阵 $\mathbf{X}$ 的第j列;

  • 令 $\rho_j=\mathbf{x}_j^\top\mathbf{r}^{(j)}$,$z_j=|\mathbf{x}_j|_2^2$

  • β的解由软阈值函数给出:$\hat{\beta}_j=\frac{1}{z_j}S(\rho_j,\lambda/2)$

    其中软阈值算子 $S(z,\gamma)$ 表示为:$S(z,\gamma)=\begin{cases}z-\gamma & \text{if } z>\gamma \ 0 & \text{if } z \leq\gamma \ z+\gamma & \text{if } z<-\gamma\end{cases}$
  • 初始设置 $\beta_1=0$,然后用 $\beta_1$ 去计算剩余 $\beta$,同样的其余 $\beta_k$ 也可用来更新 $\beta_1$,这样反复迭代直至收敛。

在变量多重共线性的时候,我们往往希望模型在足够有效的前提下,能够使用越少的变量越好,例如,当$x_1=x_2$时,我们希望得到的模型表达式为$ y=2x_1+0x_2$,而不是 $y=x_1+x_2$,这种能令部分系数为0的效果,就被称为系数稀疏化,它可以起到简化模型或者筛选变量的作用

以二维为例,岭回归的正则项 $L_N = \alpha(w_1^2 + w_2^2)$ 是一个圆,$L_E$ 要与 $L_N$ 相切于坐标轴是很难的反观Lasso的正则项 $L_N = \alpha( w_1 + w_2 )$,它是一个棱形,$L_E$ 要与 $L_N$ 相切于坐标轴却很容易因此,岭回归很难得到稀疏系数,而相比之下,LASSO回归更易得到稀疏系数。因此,在筛选变量的一种技术在建模之前,可以先用Lasso回归检测哪些变量的系数为0,然后把系数为0的变量去掉再进行建模

参考:

一篇入门之-Lasso回归模型原理与实现(含代码)-老饼讲解

线性回归大结局(岭(Ridge)、 Lasso回归原理、公式推导),你想要的这里都有 - 一无是处的研究僧 - 博客园

B站

代码示例:

from sklearn.linear_model import Lasso
import numpy as np

# 生成数据
x1 =  np.arange(0,100)                                              # 生成x1
x2 = x1*4+3                                                         # 生成x2,这里的x2与x1是线性相关的
x = np.concatenate((x1.reshape(-1, 1),x2.reshape(-1, 1)),axis=1)    # 将x1,x2合并作为x
y = x.dot([2,3])                                                    # 生成y

# Lasso模型训练
alpha =0.3                                                           # 设置正则项系数alpha
mdl = Lasso(alpha=alpha,fit_intercept=True,tol=1e-4,max_iter=1000)   # 初始化Lasso回归模型
mdl.fit(x,y)                                                         # 用数据训练模型
sim_y= mdl.predict(x)                                                # 预测


print('\nLasso训练结果:')
print('权重:'+str(mdl.coef_))
print('截距:'+ str(mdl.intercept_))
print( '均方误差:'+str(((y-sim_y)*(y-sim_y)).sum()))
print( '损失函数loss值:'+str(((y-sim_y)*(y-sim_y)).sum()/(2*x.shape[0])+alpha*(abs(mdl.coef_.sum()))))
print('迭代次数:'+str(mdl.n_iter_))