线性回归(五)—— 岭回归

岭回归

问题

在标准方程法里,我们推导出了求解回归系数的一个公式
w = ( X T X ) − 1 X T y w=(X^TX)^{-1}X^Ty w=(XTX)1XTy
这个公式一看就知道是有问题的,当 X T X X^TX XTX不是满秩的时候,不就求不了逆了吗?

X T X X^T X XTX不是满秩,也就是说明特征值中存在向量共线。

特征向量共线会带来另一个问题:过拟合。

就是说你画出的曲线弯弯扭扭,过于复杂,稍微改变一点参数的值,变化就很大。

这个其实好理解,说白了就是你就那么一点儿数据,还整一大堆特征,比如X是三行五列,三个数据,五个特征。

学过线性代数的都知道,那 X T X X^T X XTX是必不可能满秩的。

还整5个参数,就肯定过于复杂了,也就过拟合了。

那解决过拟合问题有什么办法吗?

  • 减少特征:你就这么点数据,不适合建一个复杂的模型,把一些特征砍了吧
  • 增加数据量:数据越多,模型当然越复杂,就配得上这么多的特征了
  • 正则化

正则化

J ( θ 0 , θ 1 , … , θ n ) = 1 2 m ∑ i = 1 m ( y i − h θ ( x i ) ) 2 J(\theta_0,\theta_1,…,\theta_n) = \frac{1}{2m}\sum_{i=1}^{m}{(y^i-h_\theta(x^i))^2} J(θ0,θ1,,θn)=2m1i=1m(yihθ(xi))2

代价函数原来是长这样的,我们的目的一直都是找到一个向量 θ \theta θ是的J达到最小。

上文说到,如果存在共线问题,那么就容易出现过拟合。

怎么避免呢?就是使J的大小不完全由残差(y-h)决定,我们把代价函数改成这样
J ( θ 0 , θ 1 , … , θ n ) = 1 2 m ( ∑ i = 1 m ( y i − h θ ( x i ) ) 2 + λ ∑ i = 1 m θ i 2 ) J(\theta_0,\theta_1,…,\theta_n) = \frac{1}{2m}(\sum_{i=1}^{m}{(y^i-h_\theta(x^i))^2}+\lambda\sum_{i=1}^m\theta_i^2) J(θ0,θ1,,θn)=2m1(i=1m(yihθ(xi))2+λi=1mθi2)
这样一来J就不完全由残差决定,削弱了最小二乘法的作用。

岭回归的公式推导

上面得到了一个新的代价函数,我们还是要让它最小,当然还是求导,令其为0,解方程。

上回的标准方程法我们推出
0 − X T y − X T y + 2 X T X θ = 0 0-X^Ty-X^Ty+2X^TX\theta=0 0XTyXTy+2XTXθ=0
这回还是一样,无非后面再加一项
λ ∑ i = 1 m θ i 2 = λ θ T θ \lambda\sum_{i=1}^m\theta_i^2=\lambda\theta^T\theta λi=1mθi2=λθTθ

∂ λ θ T θ ∂ θ = 2 λ θ \frac{\partial \lambda\theta^T\theta}{\partial \theta}=2\lambda\theta θλθTθ=2λθ

所以
0 − X T y − X T y + 2 X T X θ + 2 λ θ = 0 0-X^Ty-X^Ty+2X^TX\theta+2\lambda\theta=0 0XTyXTy+2XTXθ+2λθ=0
解得
θ = ( X T X − λ E ) − 1 X T y \theta=(X^TX-\lambda E)^{-1}X^Ty θ=(XTXλE)1XTy
此时我们发现,若 X T X X^TX XTX不满秩的话,没关系, ( X T X − λ E ) − 1 (X^TX-\lambda E)^{-1} (XTXλE)1一定是满秩的。

我们称 λ \lambda λ为岭系数

难就难在这个岭系数的选取上,如果选的太大,欠拟合,选的太小,过拟合。可以使用交叉验证的办法来选取一个最合适的系数。

python代码

#encoding:utf-8
import numpy as np
from sklearn import linear_model

# 读取数据
data = np.genfromtxt("../data/longley.csv",delimiter=',')
x_data = data[1:,2:]
y_data = data[1:,1]

# 创建模型
# 生成50个备选的岭系数
alphas2test = np.linspace(0.001,1)
# 用交叉验证法找最合适的岭系数
model = linear_model.RidgeCV(alphas=alphas2test,store_cv_values = True)
model.fit(x_data, y_data)
# 查看岭系数
print("岭系数为 :{0}".format(model.alpha_))

print("模型真实值为: ")
print(y_data)
print("模型预测值为:")
print(model.predict(x_data))

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值