多元线性回归模型中,如果所有特征一起上,容易造成过拟合使测试数据误差方差过大;因此减少不必要的特征,简化模型是减小方差的一个重要步骤。除了直接对特征筛选,来也可以进行特征压缩,减少某些不重要的特征系数,系数压缩趋近于0就可以认为舍弃该特征。

岭回归(Ridge Regression)和Lasso回归是在普通最小二乘线性回归的基础上加上正则项以对参数进行压缩惩罚。

首先,对于普通的最小二乘线性回归,它的代价函数是:



通过拟合系数β来使RSS最小。方法很简单,求偏导利用线性代数解方程组即可。

根据线性代数的理论可知,只要样本量合适,它就存在唯一解,也就是该模型的最优解。

这么做尽管使RSS达到了最小,它还是把所有的特征看作同样重要的程度来求解,并没有做任何特征选择,因此存在过拟合的可能。

岭回归在OLS回归模型的RSS上加上了惩罚项(l2范数),这样代价函数就成为:

λ是一个非负的调节参数,可以看到:当λ=0时,此时它与RSS一致,没有起到任何惩罚作用;当λ -> ∞时,它的惩罚项也就是无穷大,而为了使代价函数最小,只能压缩系数β趋近于0。

但是因为λ不可能为无穷大,二次项求偏导时总会保留变量本身,所以事实上它也不可能真正地将某个特征压缩为0。尽管系数较小可以有效减小方差,但依然留着一大长串特征会使模型不便于解释。这是岭回归的缺点。

lasso回归的正项则就把二次项改成了一次绝对值(l1范数),具体为:

一次项求导可以抹去变量本身,因此lasso回归的系数可以为0。这样可以起来真正的特征筛选效果。

无论对于岭回归还是lasso回归,本质都是通过调节λ来实现模型误差vs方差的平衡调整。

训练构建岭回归模型

> library(ISLR)
> Hitters = na.omit(Hitters)
> x = model.matrix(Salary~., Hitters)[,-1] # 构建回归设计矩阵
> y = Hitters$Salary
>
> library(glmnet)
> grid = 10^seq(10,-2,length = 100) # 生成100个λ值
> ridge.mod = glmnet(x,y,alpha = 0,lambda = grid) # alpha为0表示岭回归模型,为1表示lasso回归模型
>
> dim(coef(ridge.mod)) # 20*100的系数矩阵。20是19个特征+截距项,100是λ值
[1] 20 100
>
> # 显然可见l2范数越大,系数就越小
> ridge.mod$lambda[50]
[1] 11497.57
> coef(ridge.mod)[,50]
(Intercept) AtBat Hits HmRun Runs
407.356050200 0.036957182 0.138180344 0.524629976 0.230701523
RBI Walks Years CAtBat CHits
0.239841459 0.289618741 1.107702929 0.003131815 0.011653637
CHmRun CRuns CRBI CWalks LeagueN
0.087545670 0.023379882 0.024138320 0.025015421 0.085028114
DivisionW PutOuts Assists Errors NewLeagueN
-6.215440973 0.016482577 0.002612988 -0.020502690 0.301433531
> ridge.mod$lambda[60]
[1] 705.4802
> coef(ridge.mod)[,60]
(Intercept) AtBat Hits HmRun Runs
54.32519950 0.11211115 0.65622409 1.17980910 0.93769713
RBI Walks Years CAtBat CHits
0.84718546 1.31987948 2.59640425 0.01083413 0.04674557
CHmRun CRuns CRBI CWalks LeagueN
0.33777318 0.09355528 0.09780402 0.07189612 13.68370191
DivisionW PutOuts Assists Errors NewLeagueN
-54.65877750 0.11852289 0.01606037 -0.70358655 8.61181213
>
> # 输入一个新的λ,比如50,来预测系数
> predict(ridge.mod,s=50,type="coefficients")[1:20,]
(Intercept) AtBat Hits HmRun Runs
4.876610e+01 -3.580999e-01 1.969359e+00 -1.278248e+00 1.145892e+00
RBI Walks Years CAtBat CHits
8.038292e-01 2.716186e+00 -6.218319e+00 5.447837e-03 1.064895e-01
CHmRun CRuns CRBI CWalks LeagueN
6.244860e-01 2.214985e-01 2.186914e-01 -1.500245e-01 4.592589e+01
DivisionW PutOuts Assists Errors NewLeagueN
-1.182011e+02 2.502322e-01 1.215665e-01 -3.278600e+00 -9.496680e+00
>
> # 划分训练集和测试集
> set.seed(1)
> train = sample(1:nrow(x),nrow(x)/2)
> test = (-train)
> y.test = y[test]
>
> # 训练模型,并计算λ=4时的MSE
> ridge.mod = glmnet(x[train,],y[train],alpha = 0,lambda = grid,thresh = 1e-12)
> ridge.pred = predict(ridge.mod,s=4,newx = x[test,])
> mean((ridge.pred - y.test)^2)
[1] 101036.8
>
> # 增大λ为10的10^10,此时可视为各个特征都被压缩趋近为0,基本只剩截距项起作用
> ridge.pred = predict(ridge.mod,s=1e10,newx = x[test,])
> mean((ridge.pred - y.test)^2) # MSE更大
[1] 193253.1
>
> # 计算当λ=0也就是不加惩罚的最小二乘回归
> ridge.pred = predict(ridge.mod,s=0,newx = x[test,])
> mean((ridge.pred - y.test)^2) # MSE减小
[1] 114723.6
>
> ## 以上结果说明,如果λ选得不合适,结果不一定就比最小二乘回归模型更优。至于怎么选择λ,就用交叉验证法。
>
> set.seed(1)
> cv.out = cv.glmnet(x[train,],y[train],alpha=0)
> plot(cv.out)
> bestlam = cv.out$lambda.min
> bestlam # MSE最小的λ约为212
[1] 211.7416
>
> ridge.pred = predict(ridge.mod,s=bestlam,newx = x[test,])
> mean((ridge.pred - y.test)^2) # MSE减小
[1] 96015.51
>
> # 基于整个数据集构建岭回归模型
> out = glmnet(x,y,alpha = 0)
> predict(out,type = "coefficients",s=bestlam)[1:20,]
(Intercept) AtBat Hits HmRun Runs
9.88487157 0.03143991 1.00882875 0.13927624 1.11320781
RBI Walks Years CAtBat CHits
0.87318990 1.80410229 0.13074381 0.01113978 0.06489843
CHmRun CRuns CRBI CWalks LeagueN
0.45158546 0.12900049 0.13737712 0.02908572 27.18227535
DivisionW PutOuts Assists Errors NewLeagueN
-91.63411299 0.19149252 0.04254536 -1.81244470 7.21208390
>
> ## 可见岭回归模型还是19个特征,没有舍弃任何特征!

cv.out的图如下:

当log(λ)为5.+时(log(bestlam)=5.3),MSE最小。

训练构建lasso回归模型

> lasso.mod = glmnet(x[train,],y[train],alpha = 1,lambda = grid)
> plot(lasso.mod) # 可见有些特征的系数确实可以为0
>
> set.seed(1)
> cv.out = cv.glmnet(x[train,],y[train],alpha =1)
> plot(cv.out)
> bestlam = cv.out$lambda.min
> bestlam # MSE最小的λ约为16
[1] 16.78016
> lasso.pred = predict(lasso.mod,s=bestlam,newx = x[test,])
> mean((lasso.pred-y.test)^2)
[1] 100743.4
>
> ## 可见lasso回归模型与岭回归模型MSE差不多,甚至岭回归模型的MSE更小一些。
>
> out = glmnet(x,y,alpha = 1,lambda = grid)
> lasso.coef = predict(out,type="coefficients",s=bestlam)[1:20,]
> lasso.coef
(Intercept) AtBat Hits HmRun Runs
18.5394844 0.0000000 1.8735390 0.0000000 0.0000000
RBI Walks Years CAtBat CHits
0.0000000 2.2178444 0.0000000 0.0000000 0.0000000
CHmRun CRuns CRBI CWalks LeagueN
0.0000000 0.2071252 0.4130132 0.0000000 3.2666677
DivisionW PutOuts Assists Errors NewLeagueN
-103.4845458 0.2204284 0.0000000 0.0000000 0.0000000
>
> ## 可见lasso回归模型中,有12个特征系数被压缩至0。相对于岭回归模型,这里的lasso回归模型以牺牲一部分的准确度为代价,换取更简洁的模型,增加模型的可解释性。这是lasso回归的优势。

多元线性回归模型的特征压缩:岭回归和Lasso回归的更多相关文章

  1. SPSS--回归-多元线性回归模型案例解析

    多元线性回归,主要是研究一个因变量与多个自变量之间的相关关系,跟一元回归原理差不多,区别在于影响因素(自变量)更多些而已,例如:一元线性回归方程 为: 毫无疑问,多元线性回归方程应该为: 上图中的 x ...

  2. 【机器学习】正则化的线性回归 —— 岭回归与Lasso回归

    注:正则化是用来防止过拟合的方法.在最开始学习机器学习的课程时,只是觉得这个方法就像某种魔法一样非常神奇的改变了模型的参数.但是一直也无法对其基本原理有一个透彻.直观的理解.直到最近再次接触到这个概念 ...

  3. 吴裕雄 数据挖掘与分析案例实战(7)——岭回归与LASSO回归模型

    # 导入第三方模块import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom sklearn import mod ...

  4. 机器学习之五 正则化的线性回归-岭回归与Lasso回归

    机器学习之五 正则化的线性回归-岭回归与Lasso回归 注:正则化是用来防止过拟合的方法.在最开始学习机器学习的课程时,只是觉得这个方法就像某种魔法一样非常神奇的改变了模型的参数.但是一直也无法对其基 ...

  5. R语言解读多元线性回归模型

    转载:http://blog.fens.me/r-multi-linear-regression/ 前言 本文接上一篇R语言解读一元线性回归模型.在许多生活和工作的实际问题中,影响因变量的因素可能不止 ...

  6. 多元线性回归 ——模型、估计、检验与预测

    一.模型假设 传统多元线性回归模型 最重要的假设的原理为: 1. 自变量和因变量之间存在多元线性关系,因变量y能够被x1,x2-.x{k}完全地线性解释:2.不能被解释的部分则为纯粹的无法观测到的误差 ...

  7. 线性回归大结局(岭(Ridge)、 Lasso回归原理、公式推导),你想要的这里都有

    本文已参与「新人创作礼」活动,一起开启掘金创作之路. 线性模型简介 所谓线性模型就是通过数据的线性组合来拟合一个数据,比如对于一个数据 \(X\) \[X = (x_1, x_2, x_3, ..., ...

  8. 岭回归和lasso回归(转)

    回归和分类是机器学习算法所要解决的两个主要问题.分类大家都知道,模型的输出值是离散值,对应着相应的类别,通常的简单分类问题模型输出值是二值的,也就是二分类问题.但是回归就稍微复杂一些,回归模型的输出值 ...

  9. 岭回归和Lasso回归以及norm1和norm2

    norm代表的是距离,两个向量的距离:下图代表的就是p-norm,其实是对向量里面元素的一种运算: 最简单的距离计算(规范)是欧式距离(Euclidean distance),两点间距离是如下来算的, ...

随机推荐

  1. (数字IC)低功耗设计入门(七)——门级电路低功耗设计优化(续)

    前面讲解了门级功耗的优化方法,包括静动态和总体的功耗.现在来记录一下门级层次(有点书也说是在系统级)常用的一种低功耗方法--电源门控. ①电源门控概述与原理 电源门控是指芯片中某个区域的供电电源被关掉 ...

  2. pythion 第二弹

    ################################第二节################################################python中数据类型的常见的方法 ...

  3. 【2017-06-02】Jquery基础

    Jquery就是Js集成的一些方法包. 注意:Jquery的引入位置在<head></head>里. 一.选择器 1.Id选择器 $("#div1") 2. ...

  4. 当react框架遇上百度地图

      百度地图官方文档的使用指导是这样说的:在页面中引入<script type="text/javascript" src="http://api.map.baid ...

  5. mongo查询系统

    首先,我们先向集合(collections)中添加测试文档(documents).如下: > for(i=1;i<=5;i++) db.test.insert({x:i,y:i*i,z:6 ...

  6. go服务端----使用dotweb框架搭建简易服务

    使用dotweb框架搭建简易服务 go语言web框架挺多的,所谓琳琅满目,里面也有很多优秀的,比如echo.beego等,但体验下来,总是觉得哪里有点小疙瘩,后来才明白过来,echo太简单,很多日常使 ...

  7. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

  8. 基于Jmeter的轻量级接口压力测试(一)

    一.操作步骤: 1.在测试计划下新增一个线程组,并在线程组下新增一个http请求: 2.读取配置文件中的参数:在添加的http请求下添加配置元件-CSV DATA SET CONFIG 3.配置待测试 ...

  9. Spring 3整合Quartz 2实现手动设置定时任务:新增,修改,删除,暂停和恢复(附带源码)

    摘要:在项目的管理功能中,对定时任务的管理有时会很常见.但一般定时任务配置都在xml中完成,包括cronExpression表达式,十分的方便.但是如果我的任务信息是保存在数据库的,想要动态的初始化, ...

  10. PHP大批量插入mysql数据库的优化

    <?php /** * Created by PhpStorm. * User: hanks * Date: 6/2/2017 * Time: 6:03 PM */ //PHP大批量插入mysq ...