机器学习算法笔记(二十一):模型正则化之LASSO回归

LASSO回归(Least Absolute Shrinkage and Selection Operator Regression)是模型正则化的另一种方式。它的功能与岭回归类似,用于解决过拟合或者模型含有的巨大的方差误差的问题。下面我们来看一下LASSO回归的原理还有它与岭回归的不同之处。

一、什么是LASSO回归

让我们先回顾一下岭回归的原理:

其实LASSO回归本身的原理和岭回归是类似的,只是在怎么表达 θ 最小时选用了一个不同的指标:

LASSO回归的原理是用 θ 的绝对值表示 θ 的大小。

与岭回归类似,LASSO回归在损失函数是MSE的基础上,加上。让这样一个损失函数尽可能小,就相当于考虑让每一个 θ 尽可能小。α 依然是用于调节正则化项(也就是让 θ 尽可能小的程度)占优化整个损失函数程度的多少。

二、编程实现LASSO回归

新建一个工程,创建一个main.py文件。首先我们先复制上一篇文章中实现的过拟合代码,之后在下面用LASSO回归实现以下代码:

import numpy as np
import matplotlib.pyplot as plt

def plot_model(model):
    X_plot = np.linspace(-3, 3, 100).reshape(100, 1)
    y_plot = model.predict(X_plot)

    plt.scatter(x, y)
    plt.plot(X_plot[:,0], y_plot, color='r')
    plt.axis([-3, 3, 0, 6])
    plt.show()

np.random.seed(42)
x = np.random.uniform(-3.0, 3.0, size=100)
X = x.reshape(-1, 1)
y = 0.5 * x + 3 + np.random.normal(0, 1, size=100)

from sklearn.model_selection import train_test_split

np.random.seed(666)
X_train, X_test, y_train, y_test = train_test_split(X, y)

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression

def PolynomialRegression(degree):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("lin_reg", LinearRegression())
    ])

from sklearn.metrics import mean_squared_error

poly_reg = PolynomialRegression(degree=20)
poly_reg.fit(X_train, y_train)

y_predict = poly_reg.predict(X_test)
print(mean_squared_error(y_test, y_predict)) #prints: 167.9401085999025


"""以上复制上一篇文章的过拟合代码"""

#以下实现LASSO回归
from sklearn.linear_model import Lasso

def LassoRegression(degree, alpha):
    return Pipeline([
        ("poly", PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("lasso_reg", Lasso(alpha=alpha))
    ])

lasso1_reg = LassoRegression(20, 0.01)
lasso1_reg.fit(X_train, y_train)

y1_predict = lasso1_reg.predict(X_test)
print(mean_squared_error(y_test, y1_predict)) #prints: 1.1496080843259966

plot_model(lasso1_reg)

绘制出来的图像如下:

在这里取 α = 0.01,比岭回归中的第一个 α 的取值大很多。因为对于 岭回归,正则化的那一项中是 θ2,平方后的结果会比较大,所以需要让 α 值小一些来调节正则项的大小;而对于LASSO回归,正则化的那一项中是 |θ|,比岭回归中的正则化项小很多,所以在LASSO回归中 α的取值可以相对大一些。

可以看到MSE与曲线都相对原来过拟合的情况平滑了很多。我们继续增大 α 的值,分别取0.1、0.5和1,绘制结果如下:

从左到右分别为 α 取 0.1、0.5、1的图像,求得的MSE分别为1.121391、1.469908、1.840893。

和岭回归类似,LASSO回归的效果随着 α 的升高有一个先变好后变坏的过程,在使用LASSO回归时我们同样需要寻找一个最佳的 α。

三、LASSO回归与岭回归的比较

通过观察LASSO回归的图像我们注意到了一点:在岭回归中,虽然随着 α 增大,曲线越来越平缓,但它始终是一个曲线的样子;LASSO回归则不然,当 α 取0.1时,这根直线已经近乎就成为一根直线了。其实这个特性是由LASSO回归正则化的特殊性所决定的。

岭回归和LASSO回归的比较

我们使用岭回归来改进的多项式回归算法的过程中,随着 α 的改变,拟合曲线始终是曲线,直到最后变成一条几乎水平的直线。也就是说,使用 Ridge 改造的多项式回归算法,得到的模型变量前还是有系数,因此很难得到一条斜的直线。而使用 LASSO 改进的多项式回归算法,随着 α 的改变,拟合曲线会很快变成一条斜的直线(很多特征 X 前不再有系数 θ,也就是系数为零),最后慢慢变成一条几乎水平的直线,所以模型更倾向于一条直线。

LASSO趋向于使得一部分 θ 值为 0,而不是让所有的 θ 成为一个很小的值,所以可作为特征选择用。那为什么会这样呢?我们不妨使用数学的方式来推导一下。

先看岭回归,岭回归的损失函数是。现在我们单看模型正则化项,用梯度下降法的角度来看,要使得逐渐变为零(取最小值),对应的梯度为。这里的 θ0, θ1, θ2, …,θ都是有值的,我们绘制一个坐标系,随意取一个点,这个点会顺着一个各方向都有值的梯度逐渐达到0。

二维平面中岭回归正则化项归零的过程

但是LASSO不同,LASSO的损失函数中。若我们只看,对其求梯度,虽然绝对值不可导,但我们可以用一个分类函数来描述它的梯度:

这相当于,对于LASSO回归来说,若不考虑MSE,的梯度的结果就是 α 乘以一个向量,这个向量里的值不是 1、0 就是 -1。若我们以二维平面为例,在坐标系中取一个初始点,它通过梯度下降法到零的过程,会首先沿着一个斜率绝对值为1的方向走到某个坐标轴上,接着再沿着这个坐标轴达到“零”点。

二维平面中LASSO回归的归零过程,在高维空间中也是类似的。

LASSO回归不能像前面的岭回归一样以曲线的方式逐渐达到零,只能通过这样规则的方式到达零。在这个过程中,轨迹就会达到某些轴的零点,使得LASSO回归最终的结果相应的 θ 会包含很多零。

其实这也解释了“岭回归”为什么被称为“岭回归”,因为这个过程更像一个“爬山”的过程。我们梯度下降的过程就是找坡缓的地方一点一点下来,很像翻山越岭的过程所以管就称它为“岭回归”。

由此我们可以看出,LASSO回归可作为特征选择用。也正是这样的特性,LASSO回归有可能会错误的将一些有用的特征也变为零,所以从计算准确度的角度来说,还是岭回归更为准确。但如果特征数量非常多,使用LASSO回归也能起到使模型特征变小的作用。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注