草庐IT

R语言:glmnet包重点详解及多类回归实现(lasso/岭回归/弹性网)

这也是计划的一部分 2023-04-22 原文

文章目录

1.1 Glmnet介绍

Glmnet是一个通过惩罚极大似然来适应广义线性和相似模型的软件包。控制在对数尺度上计算lasso回归或弹性网回归的参数为正则化参数lambda。该算法速度非常快,并且可以利用输入矩阵x的稀疏性。

它适合线性、logistic和多项式、泊松等回归模型。它还可以拟合多元线性回归模型、定制族广义线性回归模型和lasso回归模型,在该软件包中还拥有预测、绘图、交叉验证的方法。

1.2 Glmnet数学表示

Glmnet主要解决的问题是:
m i n β 0 , β 1 N ∑ i = 1 N w i l ( y i , β 0 + β T x i ) + λ [ ( 1 − α ) ∣ ∣ β ∣ ∣ 2 2 / 2 + α ∣ ∣ β ∣ ∣ 1 ] min_{\beta_0,\beta}\frac{1}{N}\sum_{i=1}^{N}w_{i}l(y_{i},\beta_0+\beta^{T}x_{i})+\lambda [(1-\alpha )||\beta ||_{2}^{2}/2+\alpha ||\beta ||_{1}] minβ0,βN1i=1Nwil(yi,β0+βTxi)+λ[(1α)∣∣β22/2+α∣∣β1]

在λ值的网格上覆盖整个可能的解的范围。这里l(yi,ηi)函数是观测值i的负对数似然估计,例如,高斯情况下,它是12*(yi−ηi)2

1.3 Glmnet多回归方式对比

弹性网回归由α进行控制,弥补了lasso回归(α=1,默认值)和岭回归(α=0)之间的差距。参数λ控制了惩罚的整体强度。

α回归
α=1,默认值lasso回归
α=0ridge 岭回归
α=(0,1)弹性网回归

众所周知,ridge回归缩小了相互关联的预测因子的系数,而lasso回归倾向于选择其中一些而丢弃其他的,即lasso回归拥有选择变量的作用。

弹性网回归融合了这两者的优缺点:如果预测因子在组中相关,α=0.5倾向于选择或忽略整个组的特征。这是一个更高级别的参数,用户可能预先选择一个α值或尝试几个不同的α值。函数中α参数的一个用途是求数值稳定性;例如,当α更加接近1时,弹性网会更加与lasso回归相似,但消除了极端数据使得模型过于简单的情况。

1.4 Glmnet代码原理

glmnet算法采用循环坐标下降法,在其他参数不变的情况下,依次优化目标函数,并重复循环,直到收敛。该R包还利用强规则对活动集进行有效约束。由于高效的更新和技术,如热启动和活动集收敛,该算法可以非常快速地计算。

该代码可以处理稀疏的输入矩阵格式,以及系数的范围限制。glmnet的核心代码是一组Fortran子程序,这使得其执行速度非常快。

1.5 Glmnet安装与载入

如其他所有R包相似,安装glmnet只需要一行代码。

install.packages("glmnet")

在R Studio中设置为国内的镜像网站 能够加快包的安装速度。

library(glmnet)
1.6 Glmnet回归使用

载入R自带的数据包来进行Glmnet的展示

data("MultinomialExample")

在我们不调整参数的默认情况下,它使用的是高斯分布或者说最小二乘来进行回归。首先确定需要使用的回归方法,

而我们首先需要确定使用的回归方法

如Lasso回归、Ridge回归、Elastic net等。

fit = glmnet(data_x, data_y,alpha =0.5,standardize=TRUE)

alpha=0 岭回归 不进行变量的选择

alpha=1 lasso回归 进行变量的选择

其他[0,1]间取值则是Elastic net回归。

fit = glmnet(MultinomialExample$x,MultinomialExample$y,alpha = 0.5,standardize=TRUE)

standardize进行标准化 避免量纲影响。

Fit是glmnet类的一个对象,它包含适合模型的所有相关信息,以供进一步使用。不必直接使用该对象进行分析。在Glmnet包中对fit对象提供了各种方法,如plot, print, coef和predict,使我们能够更高效地执行这些任务。

1.7 Glmnet回归结果分析

打印拟合结果

print(fit)
> #打印拟合结果
> print(fit)

Call:  glmnet(x = MultinomialExample$x, y = MultinomialExample$y, alpha = 0,      standardize = TRUE) 

    Df  %Dev  Lambda
1   30  0.00 267.300
2   30  0.28 243.600
3   30  0.30 221.900
4   30  0.33 202.200
5   30  0.37 184.200
6   30  0.40 167.900
7   30  0.44 153.000
8   30  0.48 139.400
9   30  0.53 127.000
10  30  0.58 115.700
11  30  0.64 105.400
12  30  0.70  96.060
13  30  0.76  87.530
14  30  0.84  79.750
15  30  0.92  72.670
16  30  1.00  66.210
17  30  1.10  60.330
18  30  1.20  54.970
19  30  1.32  50.090
20  30  1.44  45.640
21  30  1.58  41.580
22  30  1.73  37.890
23  30  1.89  34.520
24  30  2.07  31.460
25  30  2.26  28.660
26  30  2.47  26.120
27  30  2.69  23.800
28  30  2.94  21.680
29  30  3.21  19.760
30  30  3.50  18.000
31  30  3.81  16.400
32  30  4.15  14.940
33  30  4.52  13.620
34  30  4.92  12.410
35  30  5.34  11.300
36  30  5.80  10.300
37  30  6.29   9.385
38  30  6.82   8.552
39  30  7.38   7.792
40  30  7.98   7.100
41  30  8.62   6.469
42  30  9.29   5.894
43  30 10.01   5.371
44  30 10.76   4.893
45  30 11.55   4.459
46  30 12.38   4.063
47  30 13.25   3.702
48  30 14.15   3.373
49  30 15.08   3.073
50  30 16.04   2.800
  • 它从左到右显示非零系数的数量(Df),解释的百分比(null)偏差(%Dev)和λ的值(Lambda)。
  • glmnet在默认情况下会拟合100个lambda值的模型。
  • 如果%Dev没有从一个lambda到下一个lambda进行足够大小的更改,它会认为拟合已经完成,提前停止,以提高计算速度。
  • 为了简洁起见,我们在这里截断了打印结果,只展示了部分。
1.8 Glmnet回归结果可视化

我们可以通过plot()来可视化回归结果

plot(fit)

弹性网:

lasso回归:

每条曲线对应一个变量。它显示了当λ变化时,它的系数相对于整个系数向量的ℓ1范数的路径。上面的轴表示在当前λ非零系数的数量,这是lasso的有效自由度(df)。用户可能还希望对曲线进行注释:这可以通过在plot命令中设置label = TRUE来实现。

岭回归:

能够明显观察到岭回归下变量始终大于0,即解释变量未有被筛选掉;而相比之下,弹性网与lasso回归在lambda改变时,部分变量消失了,不再进行模型解释。

我们可以通过如下代码得到序列范围内一个或多个λ处的模型系数:

获取超参数=0.1时的参数估计结果

coef(fit,s=0.1)
1.9 Glmnet模型评价方法

函数glmnet返回一系列模型供用户选择。在许多情况下,用户可能更喜欢软件来选择其中之一。交叉验证可能是完成该任务最简单、使用最广泛的方法。简历。Glmnet是这里进行交叉验证的主要函数,以及各种支持方法,如绘图和预测。

十折交叉验证进行模型评价:

cvfit <- cv.glmnet(data_x, data_y,nfolds = 10) 

cv.glmnet返回cv.glmnet对象,一个包含交叉验证匹配的所有成分的列表。与glmnet一样,不鼓励直接使用该对象,而是利用其软件包设计的函数。

绘图展示超参数的影响:

plot(cvfit)

这将绘制交叉验证曲线(红色虚线)以及沿λ序列(误差条)的上下标准偏差曲线。沿着λ序列的两个特殊值用垂直的虚线表示。

1.10 Glmnet选择最佳模型

打印最佳的超参数 帮助用户选择:

lambda.min下的模型交叉验证误差最小。lambda.1se给出了最正则化的模型,使得交叉验证误差在最小值的一个标准误差内。

print(cvfit$lambda.min) 
print(cvfit$lambda.1se)
> print(cvfit$lambda.min) 
[1] 0.02866132
> print(cvfit$lambda.1se)
[1] 0.07266689
1.11 Glmnet预测

设置种子 随机生成新数据

set.seed(29)
nx <- matrix(rnorm(500 * 30), 500, 30)

通过已经训练好的模型 进行预测

predict(fit, newx = nx, s = c(0.1, 0.05))
> predict(fit, newx = nx, s = c(0.1, 0.05))
              s1        s2
  [1,] 2.7309311 2.7732605
  [2,] 2.2859731 2.2954917
  [3,] 2.2992034 2.3208074
  [4,] 1.6894255 1.6735020
  [5,] 2.5623190 2.5941302
  [6,] 1.5733710 1.5388561

有关R语言:glmnet包重点详解及多类回归实现(lasso/岭回归/弹性网)的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  4. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  5. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  6. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  9. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  10. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

随机推荐