sklearn - 岭回归(Ridge)和套索回归(Lasso)

一: 拟合

(一): 过拟合与欠拟合

机器学习中一个重要的话题便是模型的泛化能力,泛化能力强的模型才是好模型,对于训练好的模型,若在训练集表现差,不必说在测试集表现同样会很差,这可能是欠拟合导致;若模型在训练集表现非常好,却在测试集上差强人意,则这便是过拟合导致的; 过拟合与欠拟合也可以用 Bias 与 Variance 的角度来解释,欠拟合会导致高 Bias; 过拟合会导致高 Variance ,所以模型需要在 Bias 与 Variance 之间做出一个权衡

Bias 即为模型的期望输出与其真实输出之间的差异

Variance 刻画了不同训练集得到的模型的输出与这些模型期望输出的差异

一般在模型效果差的第一个想法是增多数据,其实增多数据并不一定会有更好的结果,因为欠拟合时增多数据往往导致效果更差,而过拟合时增多数据会导致 Gap 的减小,效果不会好太多,所以当模型效果很差时,应该检查模型是否处于欠拟合或者过拟合的状态,而不要一味的增多数据量,关于过拟合与欠拟合,这里给出几个解决方法。

(二): 常用解决办法

(1)解决欠拟合的方法:

1、增加新特征,可以考虑加入进特征组合、高次特征,来增大假设空间;

2、尝试非线性模型,比如核SVM 、决策树、DNN等模型;

3、如果有正则项可以较小正则项参数 λ \lambda λ;

4、Boosting ,Boosting 往往会有较小的 Bias,比如 Gradient Boosting 等.

(2)解决过拟合的方法:

1、交叉检验,通过交叉检验得到较优的模型参数;

2、特征选择,减少特征数或使用较少的特征组合,对于按区间离散化的特征,增大划分的区间;

3、正则化,常用的有 L1、L2 正则。而且 L1正则还可以自动进行特征选择;

4、如果有正则项则可以考虑增大正则项参数 lambda;

5、增加训练数据可以有限的避免过拟合;

6、Bagging ,将多个弱学习器Bagging 一下效果会好很多,比如随机森林等.

二: Ridge回归 - 岭回归

1: Ridge回归 - 梯度下降(在线性回归后加上L2正则项-解决过拟合问题)

损失函数:
J ( w ) = min ⁡ w ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 2 2 J(w) = \min\limits_w||Xw-y||_2^2 + \alpha||w||_2^2 J(w)=wminXwy22+αw22

1 m \frac{1}{m} m1表示m个样本求平均:
J ( w ) = 1 m ∑ i = 1 m ( ∣ ∣ X i w − y i ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 2 2 ) J(w) = \frac{1}{m}\sum_{i=1}^m(||X_iw-y_i||_2^2 + \alpha||w||_2^2) J(w)=m1i=1m(Xiwyi22+αw22)

J ( w ) = 1 m [ ( X w − y ) T ( X w − y ) + α w T w ] J(w) = \frac{1}{m}[(Xw-y)^T(Xw-y)+\alpha w^Tw] J(w)=m1[(Xwy)T(Xwy)+αwTw]

求解梯度(导数):
J ′ ( w ) = 2 m [ X T ( X w − y ) + α w ] J'(w) = \frac{2}{m}[X^T(Xw-y)+\alpha w] J(w)=m2[XT(Xwy)+αw]

∇ w J ( w ) = 2 m [ X T ( X w − y ) + α w ] \nabla_wJ(w) = \frac{2}{m} [X^T(Xw - y) +\alpha w] wJ(w)=m2[XT(Xwy)+αw]

更新w:
w = w − ϵ ∇ w J ( w ) w = w-\epsilon \nabla_wJ(w) w=wϵwJ(w)

w = w − 2 m ϵ [ X T ( X w − y ) + α w ] w = w -\frac{2}{m}\epsilon[X^T(Xw-y)+\alpha w] w=wm2ϵ[XT(Xwy)+αw]

w = w − 2 ϵ m X T ( X w − y ) − 2 α ϵ m w w = w -\frac{2\epsilon}{m} X^T(Xw-y)-\frac{2\alpha\epsilon}{m} w w=wm2ϵXT(Xwy)m2αϵw

w = [ w − 2 ϵ m X T ( X w − y ) ] − 2 α ϵ m w w = [w -\frac{2\epsilon}{m} X^T(Xw-y)]-\frac{2\alpha\epsilon}{m} w w=[wm2ϵXT(Xwy)]m2αϵw

如上公式, 中括号内的公式是线性回归的更新规则, 也就是说岭回归就是在 线性回归的基础上多减了一项, 2 α ϵ m w \frac{2\alpha\epsilon}{m} w m2αϵw, 其

中:

α > = 0 \alpha >= 0 α>=0缩放强度

ϵ > = 0 \epsilon>=0 ϵ>=0步幅

m > 0 m>0 m>0样本数量

当w是正数时: 2 ϵ α m w \frac{2\epsilon\alpha}{m}w m2ϵαw 为正数,此时岭回归就相当于在线性回归的基础上减去一个正数, 所以系数w变小

当w是负数时: 2 ϵ α m w \frac{2\epsilon\alpha}{m}w m2ϵαw 为负数,此时岭回归就相当于在线性回归的基础上减去一个负数, 所以系数w的绝对值变小

正则项:w变小的好处:防止过拟合

岭回归适用范围:

方程完全共线性(方程内有方程是其他方程的倍数,相当于重复方程):

  • x+ 2y + 22 = 9
  • 2x +4y + 42 = 18

岭回归适用于数据中存在共线性的情况(非满秩矩阵)

2: Ridge回归正规方程推导:

损失函数:
J ( w ) = min ⁡ w ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 2 2 J(w) = \min\limits_w||Xw-y||_2^2 + \alpha||w||_2^2 J(w)=wminXwy22+αw22

J ( w ) = ( X w − y ) T ( X w − y ) + α w T w J(w)=(Xw-y)^T(Xw-y)+\alpha w^Tw J(w)=(Xwy)T(Xwy)+αwTw

求导:
∇ w J ( w ) = 2 X T X w − 2 X T y + 2 α w \nabla_wJ(w)=2X^TXw-2X^Ty+2\alpha w wJ(w)=2XTXw2XTy+2αw
令导数为0:
2 X T X w − 2 X T y + 2 α w = 0 2X^TXw-2X^Ty+2\alpha w=0 2XTXw2XTy+2αw=0

X T X w − X T y + α I w = 0 X^TXw-X^Ty+\alpha Iw=0 XTXwXTy+αIw=0

( X T X + α I ) w − X T y = 0 (X^TX+\alpha I)w-X^Ty=0 (XTX+αI)wXTy=0

( X T X + α I ) w = X T y (X^TX+\alpha I)w=X^Ty (XTX+αI)w=XTy

( X T X + α I ) − 1 ( X T X + α I ) w = ( X T X + α I ) − 1 X T y (X^TX+\alpha I)^{-1}(X^TX+\alpha I)w=(X^TX+\alpha I)^{-1}X^Ty (XTX+αI)1(XTX+αI)w=(XTX+αI)1XTy

推导得出w:
w = ( X T X + α I ) − 1 X T y w=(X^TX+\alpha I)^{-1}X^Ty w=(XTX+αI)1XTy

3: Ridge回归和线性回归对比

import numpy as np
from sklearn.linear_model import LinearRegression, Ridge, Lasso
# 将数据一分为二
from sklearn.model_selection import train_test_split
# 均方误差
from sklearn.metrics import mean_squared_error
import pandas as pd


# 加载数据
# 加载训练数据
# train = pd.read_table('./zhengqi_train.txt') 和下面一行的效果相同
train = pd.read_csv('./zhengqi_train.txt', sep = '\t')
train
# 加载测试数据
test = pd.read_table('./zhengqi_test.txt')
test


# 将训练数据分乘特征值和目标值
# 特征, 影响目标值的因素
X = train.iloc[:, :-1]
# 目标值
y = train['target']

# 算法评估, 将上面的数据分成两份,一部分用来训练, 一部分用来测试
X_train, X_validation, y_train, y_validation = train_test_split(X, y, test_size = 0.2)


# 使用普通线性回归模型
linear = LinearRegression()
linear.fit(X_train, y_train)
y_ = linear.predict(X_validation)
mean_squared_error(y_validation,y_)   # 均方误差
'''0.11713370444738197'''

# 使用线性模型预测测试数据
y_commit = linear.predict(test)
# 保存数据到本地
s = pd.Series(y_commit)
s.to_csv('./linear_result.txt', index=False, header = False)


# 使用岭回归模型
ridge = Ridge(alpha=256)   # alpha值
ridge.fit(X_train, y_train)
y_ = ridge.predict(X_validation)
mean_squared_error(y_validation,y_)
'''0.13427749653218798'''

y_commit = ridge.predict(test)
pd.Series(y_commit).to_csv('./ridge_result.txt', index=False, header = False)

将生成的数据上传到阿里天池,与实际数据对比,计算均方误差时, 使用岭回归模型得到的数据比使用线性回归模型得到的数据的均方误差要小,说明对该组数据,岭回归效果更好

三: lasso回归 - 套索回归

1: lasso回归 - 梯度下降(在线性回归后加上L1正则项-解决过拟合问题)

罗斯回归方程:
min ⁡ w 1 2 n s a m p l e s ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 1 \min\limits_w \frac{1}{2n_{samples}}||Xw-y||_2^2+\alpha ||w||_1 wmin2nsamples1Xwy22+αw1
方程转换:
J ( w ) = ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 1 J(w)=||Xw-y||_2^2+\alpha ||w||_1 J(w)=Xwy22+αw1
向量的1范数: 取绝对值的最大值

由于求导时方程中不能有绝对值符号, 所以分情况讨论: w是正数或者为负数

求导:
∇ w J ( w ) = 2 X T X w − 2 X T y + α s g n ( w ) \nabla_wJ(w)=2X^TXw-2X^Ty+\alpha sgn(w) wJ(w)=2XTXw2XTy+αsgn(w)
sgn(w)是符号表示函数: sgn(w)代表着w>0那么sgn(w)=+1;如果w<0那么sgn(W)=-1

梯度下降中系数w的更新规则:
w = w − ϵ ∇ w J ( w ) w = w - \epsilon \nabla_wJ(w) w=wϵwJ(w)

w = w − ϵ ( X T X w − X T y ) − ϵ α s g n ( w ) w = w - \epsilon(X^TXw-X^Ty)-\epsilon \alpha sgn(w) w=wϵ(XTXwXTy)ϵαsgn(w)

w = [ w − ϵ ( X T X w − X T y ) ] − ϵ α s g n ( w ) w = [w - \epsilon(X^TXw-X^Ty)]-\epsilon \alpha sgn(w) w=[wϵ(XTXwXTy)]ϵαsgn(w)

当w为正时候sgn(w) =+1,直接去掉减去入所以正的w变小了

当w为负时候sgn(w)=-1,负号变成了正号加上了入,负数w取向零

Lasso回归系数可以缩减到0,岭回归不可以

系数(权重)变成0了,说明:可有可无,属性不重要

2: lasso回归与岭回归和线性回归对比

import numpy as np
from sklearn.linear_model import LinearRegression, Ridge, Lasso
# 将数据一分为二
from sklearn.model_selection import train_test_split
# 均方误差
from sklearn.metrics import mean_squared_error
import pandas as pd


# 加载数据
# 加载训练数据
# train = pd.read_table('./zhengqi_train.txt') 和下面一行的效果相同
train = pd.read_csv('./zhengqi_train.txt', sep = '\t')
train
# 加载测试数据
test = pd.read_table('./zhengqi_test.txt')
test


# 将训练数据分乘特征值和目标值
# 特征, 影响目标值的因素
X = train.iloc[:, :-1]
# 目标值
y = train['target']

# 算法评估, 将上面的数据分成两份,一部分用来训练, 一部分用来测试
X_train, X_validation, y_train, y_validation = train_test_split(X, y, test_size = 0.2)


# 使用普通线性回归模型
linear = LinearRegression()
linear.fit(X_train, y_train)
y_ = linear.predict(X_validation)
mean_squared_error(y_validation,y_)   # 均方误差
'''0.11713370444738197'''

# 使用线性模型预测测试数据
y_commit = linear.predict(test)
# 保存数据到本地
s = pd.Series(y_commit)
s.to_csv('./linear_result.txt', index=False, header = False)


# 使用岭回归模型
ridge = Ridge(alpha=256)   # alpha值
ridge.fit(X_train, y_train)
y_ = ridge.predict(X_validation)
mean_squared_error(y_validation,y_)
'''0.13427749653218798'''

y_commit = ridge.predict(test)
pd.Series(y_commit).to_csv('./ridge_result.txt', index=False, header = False)



# 使用lasso回归模型
lasso = Lasso(alpha=256)
lasso.fit(X_train, y_train)
y_ = lasso.predict(X_validation)
mean_squared_error(y_validation,y_)
'''0.9351911263395224'''

y_commit = lasso.predict(test)
pd.Series(y_commit).to_csv('./lasso_result.txt', index=False, header = False)

将生成的数据上传到阿里天池,与实际数据对比,计算均方误差时, 使用lasso回归模型得到的数据比使用岭回归模型和线性回归模型得到的数据的均方误差要小,说明对该组数据,lasso回归效果最好

套索回归适用于稀松矩阵(大部分系数是0)

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值