【机器学习】知道线性回归,但你知道什么是岭回归(Ridge Regression)和LASSO回归吗?

摘要: 线性回归是众所周知的非常基本的算法,但也存在很多不足。为了是算法模型能够具有更好的泛化能够,不至于模型过拟合,当前研究就传统的线性回归算法的基础上增加正则项,添加 l 1 l_1 l1正则就是LASSO回归,添加 l 2 l_2 l2正则就是岭回归,本文通过对这几个算法进行比较来说明各自的特点。

关键字: 线性回归,岭回归,LASSO回归。

前言

线性回归算法是机器学习算法中的一个入门算法,简单容易理解,但是传统的线性回归算法有很多缺点,容易过拟合等等。为了克服这种缺点,当前研究提出增加正则项(很多机器学习方法都使用)的方式降低模型的过拟合,提高模型的泛化能力。

1 传统的线性回归模型

传统对于有一个有 n n n个特征的数据 x x x的线性回归模型如下,也可参考我之前的文章:【机器学习】吴恩达机器学习视频作业-线性回归。
h ( x ) = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b h\left( x \right) =w_1x_1+w_2x_2+\cdots +w_nx_n+b h(x)=w1x1+w2x2++wnxn+b
对于一些线性回归的任务可以做,但是不采取一些方式容易过拟合(机器学习算法都是如此)。我们使用波斯顿房价数据集看看,处理过的波斯顿房价数据集的特征增加到了105个。


from sklearn.linear_model import LinearRegression
from sklearn.datasets import load_boston
from sklearn.preprocessing import MinMaxScaler, PolynomialFeatures
from sklearn.model_selection import train_test_split

def load_extended_boston():
    boston = load_boston()
    X = boston.data
    X = MinMaxScaler().fit_transform(boston.data)  # 数据归一化处理
    # 使用多项式的方法来进行的,如果有a,b两个特征,那么它的2次多项式为(1,a,b,a^2,ab, b^2),degree:控制多项式的度
    # interaction_only: 默认为False,如果指定为True,那么就不会有特征自己和自己结合的项,上面的二次项中没有a^2和b^2。
    # include_bias:默认为True。如果为True的话,那么就会有上面的 1那一项。
    X = PolynomialFeatures(degree=2, include_bias=False).fit_transform(X)
    return X, boston.target
X, y = load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
lr = LinearRegression().fit(X_train, y_train)
print("Training set score:{:.2f}".format(lr.score(X_train, y_train)))  # 训练集的测试分数
print("Training set score:{:.2f}".format(lr.score(X_test, y_test)))  # 测试集的测试分数
"""
Training set score:0.95
Training set score:0.61
"""

从测试得分可以看出,在训练集得分较高而测试集分数较低,也就是说过拟合了。
补充: 如何查看训练好模型中的权重参数 w w w和截距 b b b呢?其分布保存在:coef_intercept_,查看方式如下:

print("lr.coef_:{}".format(lr.coef_))
print("lr.intercept_:{}".format(lr.intercept_))
"""
lr.coef_:[-4.12710947e+02 -5.22432068e+01 -1.31898815e+02 -1.20041365e+01
 -1.55107129e+01  2.87163342e+01  5.47040992e+01 -4.95346659e+01
....
  1.19553429e+01  6.77025947e-01  2.73452009e+00  3.03720012e+01]
lr.intercept_:30.934563673637694
"""

2 岭回归

岭回归也是一种用于回归的线性模型,与传统的线性模型有很多相似之处。为了降低过拟合的情况,也就是说不仅要在训练集上的数据效果好,在测试集上的数据也要好,这样模型才具有不错的泛化能力。这里是希望特征数据的权重尽可能小,减小数据受权重的制约,一般来说,我们是权重参数 w w w接近于0。这里就引入正则化(regularization),避免模型过拟合。岭回归就是具有 l 2 l_2 l2正则化的回归,相关内容可以参考:【机器学习】模型优化改进建议。下面我们来看看如何使用sklearn实现岭回归。

from sklearn.linear_model import Ridge

ridge = Ridge().fit(X_train, y_train)
print("Training set score:{:.2f}".format(ridge.score(X_train, y_train)))  # 训练集的测试分数
print("Training set score:{:.2f}".format(ridge.score(X_test, y_test)))  # 测试集的测试分数
"""
Training set score:0.89
Training set score:0.75
"""

从结果可以看出Ridge训练集的分数低于LinerRegression,在测试集上的分数更高。这就是使用正则降低过拟合的结果。当然我们也可以通过修改参数alpha指定正则化项的系数,Ridge默认是1。当然,alpha过大过小都不好,这也是需要进行模型调参了,因为这是需要根据数据集进行处理的。例如我们使用alpha=0.5来测试一下模型的性能:

ridge = Ridge(alpha=0.5).fit(X_train, y_train)
print("Training set score:{:.2f}".format(ridge.score(X_train, y_train)))  # 训练集的测试分数
print("Training set score:{:.2f}".format(ridge.score(X_test, y_test)))  # 测试集的测试分数
"""
Training set score:0.90
Training set score:0.77
"""

注意,减小alpha可以让系数(w)受到的限制更小,当alpha特别小的时候就可以普通的LinearRegression没什么区别了。使用正则化进行优化模型的相关概念在【机器学习】模型优化改进建议已经介绍,不再赘述。

3 lasso回归

这种方法是 l 1 l_1 l1正则化(就是系数绝对值之和)。使用lasso时某些系数刚好为0(这是一个最优化问题,可参考文献1),也就是一些特征就会被模型忽略了。下面我们做一下实验:

from sklearn.linear_model import Lasso
import numpy as np
lasso = Lasso().fit(X_train, y_train)
print("Training set score:{:.2f}".format(lasso.score(X_train, y_train)))
print("Test set score:{:.2f}".format(lasso.score(X_test, y_test)))
print("Number of features used:{}".format(np.sum(lasso.coef_ != 0)))
"""
Training set score:0.29
Test set score:0.21
Number of features used:4
"""

可以看出这个结果惨不忍睹,使用的特征也仅仅只有4个。这时我们就需要通过控制正则化的系数alpha(默认为1.0)来改变这个状况。同时,为了降低欠拟合,可以尝试较小alpha,这个和Ridge相似,并且还需要增加max_iter的值,即增加运行迭代的最大次数。修改如下:

lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)
print("Training set score:{:.2f}".format(lasso001.score(X_train, y_train)))
print("Test set score:{:.2f}".format(lasso001.score(X_test, y_test)))
print("Number of features used:{}".format(np.sum(lasso001.coef_ != 0)))
"""
Training set score:0.90
Test set score:0.77
Number of features used:33
"""

这个时候我们就可以看出,不管是在训练集上还是测试集上表现得都挺不错,同时也只是用了105个特征中的33个。当然如果将alpha这个参数调得太小也就和传统得LinearRegression类似了。

Reference

  1. Lasso回归 https://blog.csdn.net/xiaozhu_1024/article/details/80585151

你可能感兴趣的:(Machine,Learning,(ML))