在R中使用Lars(或glmnet)软件包中的LASSO进行变量选择


39

抱歉,这个问题有点基本。

我正在寻找在R中的多元线性回归模型中使用LASSO变量选择的方法。我有15个预测变量,其中之一是分类的(会引起问题吗?)。设置好和我使用以下命令:ÿxy

model = lars(x, y)
coef(model)

我的问题是我何时使用coef(model)。这将返回一个包含15行的矩阵,每次添加一个额外的预测变量。但是,没有建议选择哪种模型。我错过了什么吗?有没有办法让我的lars包返回一个“ 最佳 ”模型?

还有其他文章建议使用glmnet代替,但这似乎更复杂。尝试如下,使用相同的和。我在这里错过了什么吗?: ÿxy

cv = cv.glmnet(x, y)
model = glmnet(x, y, type.gaussian="covariance", lambda=cv$lambda.min)
predict(model, type="coefficients")

最后一条命令返回我的变量列表,大多数变量带有系数,尽管有些为= 0。这是LASSO 选择的“ 最佳 ”模型的正确选择吗?然后,如果我用所有具有系数的变量拟合线性模型,则not=0得到的系数估计值非常相似,但略有不同。有什么区别的原因吗?用LASSO选择的这些变量重新拟合线性模型并将其作为我的最终模型是否可以接受?否则,我将看不到任何有意义的p值。我错过了什么吗?

是否

type.gaussian="covariance" 

确保glmnet使用多元线性回归?

变量的自动归一化是否会完全影响系数?有什么方法可以在LASSO程序中包括交互项?

我希望更多地使用此过程来演示如何使用LASSO,而不是将其实际用于任何重要的推断/预测(如果发生任何变化)的任何模型。

感谢您抽出时间来阅读。对于LASSO / lars / glmnet的任何一般性评论也将不胜感激。


4
附带说明一下,如果要解释结果,请确保证明套索选择的变量集是稳定的。这可以使用蒙特卡洛模拟或通过引导自己的数据集来完成。
Frank Harrell 2013年

Answers:


28

glmnet一旦掌握了它,使用起来就非常容易,这要归功于其出色的小插图,网址为http://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html(您也可以查看CRAN软件包页面)。至于最好的lambda glmnet,经验法则是使用

cvfit <- glmnet::cv.glmnet(x, y)
coef(cvfit, s = "lambda.1se")

代替lambda.min

为此,lars您必须手动进行。这是我的解决方案

cv <- lars::cv.lars(x, y, plot.it = FALSE, mode = "step")
idx <- which.max(cv$cv - cv$cv.error <= min(cv$cv))
coef(lars::lars(x, y))[idx,]

请记住,这并不完全相同,因为这是在套索结(输入变量时)而不是在任何时候停止的。

请注意,这glmnet是目前首选的软件包,它比积极地维护着,而不是lars,并且以前对glmnetvs 还有疑问lars(使用的算法有所不同)。

至于使用套索选择变量然后拟合OLS的问题,这是一个持续的辩论。Google for OLS发布了Lasso,并且有一些论文讨论了该主题。甚至统计学习元素的作者也承认这是可能的。

编辑:这里是代码,以更准确地再现什么glmnet的呢lars

  cv <- lars::cv.lars(x, y, plot.it = FALSE)
  ideal_l1_ratio <- cv$index[which.max(cv$cv - cv$cv.error <= min(cv$cv))]
  obj <- lars::lars(x, y)
  scaled_coefs <- scale(obj$beta, FALSE, 1 / obj$normx)
  l1 <- apply(X = scaled_coefs, MARGIN = 1, FUN = function(x) sum(abs(x)))
  coef(obj)[which.max(l1 / tail(l1, 1) > ideal_l1_ratio),]

+1好答案!您或任何人都可以详细说明为什么lambda.1se是经验法则而不是lambda.min吗?
Erosennin

经过4年的撰写(并且有一段时间没有使用套索),我的记忆消失了。抱歉!
Juancentro

8

由于我认为我已经解决了正确的解决方案,所以我刚才又回到了这个问题。

这是使用mtcars数据集的副本:

library(glmnet)
`%ni%`<-Negate(`%in%')
data(mtcars)

x<-model.matrix(mpg~.,data=mtcars)
x=x[,-1]

glmnet1<-cv.glmnet(x=x,y=mtcars$mpg,type.measure='mse',nfolds=5,alpha=.5)

c<-coef(glmnet1,s='lambda.min',exact=TRUE)
inds<-which(c!=0)
variables<-row.names(c)[inds]
variables<-variables[variables %ni% '(Intercept)']

“变量”为您提供了解决最佳解决方案的变量列表。


1
我正在查看代码,但发现尚未定义“测试”,因此代码:“ final.list <-testing [-removed] #removing variables”给出错误:找不到对象所以查看代码假设应该使用“ cp.list”代替“ testing”,这样代码将是:final.list <-cp.list [-removed]#删除变量final.list <-c(final.list,重复)#添加被删除并随后添加的var,请让我知道这是否正确亲切的问候

3
`%ni%`<-Negate(`%ni%`); ##看起来不对。而`%ni%`<-Negate(`%in%`); ##看起来不错。我认为stackexchange格式化程序将其弄乱了……
克里斯

您能否详细说明如何选择nfolds=5alpha=0.5参数?
科林

7

也许与正向选择逐步回归的比较会有所帮助(请参阅以下作者之一链接到该站点的链接http://www-stat.stanford.edu/~tibs/lasso/simple.html)。这是《统计学习的要素》(第3.4.4章)(在线免费提供)中使用的方法。我认为那本书的第3.6章有助于理解最小二乘法,最佳子集和套索之间的关系(以及其他一些过程)。我还发现采用系数t(coef(model))和write.csv的转置很有帮助,这样我就可以在Excel中将其与旁边的plot(model)副本一起打开。您可能要按最后一列排序,该列包含最小二乘估计值。然后,您可以清楚地看到每个分段如何添加每个变量以及结果系数如何变化。当然,这还不是全部,但希望它将是一个开始。


3

larsglmnet在原始矩阵上运行。要包含交互项,您将必须自己构造矩阵。这意味着每次互动都需要一列(如果您有因素,则是每个因素每个级别)。调查lm()一下它是如何做到的(警告:有龙)。

要立即执行此操作,请执行以下操作:若要手动创建一个交互术语,您可以(但可能不应该这样做,因为它很慢):

int = D["x1"]*D["x2"]
names(int) = c("x1*x2")
D = cbind(D, int)

然后在Lars中使用它(假设您有y踢踢的机会):

lars(as.matrix(D), as.matrix(y))

希望我能在其他问题上为您提供更多帮助。我找到这是因为lars使我感到悲伤,并且它和网络上的文档都很薄。


2
“警告:有龙”这很容易做到model.matrix()
格里高尔2014年

2

LARS解决了整个解决方案的路径。解路径是分段线性的-解在其中变化的有限数量的“陷波”点(即,正则化参数的值)。

因此,您获得的解决方案矩阵就是所有可能的解决方案。在返回的列表中,它还应为您提供正则化参数的值。


谢谢您的回答。有没有办法显示正则化参数的值?另外,是否有一种方法可以根据此参数在解决方案之间进行选择?(参数lambda也是吗?)
詹姆斯(James

请注意,分段线性并不意味着线是水平的,因此解决方案一直随lambda改变。例如,出于预测目的,不仅节点之间而且节点之间,将具有λ值的网格。节点之间的某个点很有可能产生最佳的更好的预测性能。
理查德·哈迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.