使用 R 中 lars(或 glmnet)包中的 LASSO 进行变量选择

机器算法验证 特征选择 套索 网络 拉尔斯
2022-02-06 12:03:00

对不起,如果这个问题有点基本。

我希望将 LASSO 变量选择用于 R 中的多元线性回归模型。我有 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个回答

借助http://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html中的出色插图(您也可以查看 CRAN 包页面),一旦您掌握了它,使用glmnet就非常容易。至于 的最佳 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 post 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),]

因为我认为我已经解决了正确的解决方案,所以我不久前又回到了这个问题。

这是使用 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)']

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

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

lars并对glmnet原始矩阵进行操作。要包含交互项,您必须自己构建矩阵。这意味着每个交互作用一列(如果您有因素,则每个因素的每个级别)。看看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 让我很伤心,而且它和网络上的文档非常薄。