R中glmnet的岭回归;使用glmnet包计算不同lambda值的VIF

时间:2017-07-01 14:26:36

标签: r regression modeling glmnet

我有一组多线性变量,我试图使用岭回归来解决这个问题。我在R中使用GLMNET包,alpha = 0(用于岭回归)。

library(glmnet)

我有一系列lambda值;我通过cv.glmnet选择最好的lambda值

lambda <- 10^seq(10, -2, length = 100)

- 创建模型矩阵并分配y变量

x <- model.matrix(dv ~ ., datamatrix) [,-1]
y <- datamatrix$dv

- 使用交叉验证来确定最佳lambda并使用该lambda值预测y

ridge.mod <- glmnet(x, y, alpha = 0, lambda = lambda)
cv.out <- cv.glmnet(x, y, alpha = 0)
ridge.pred <- predict(ridge.mod, s = cv.out$lambda.min, newx = x)

我能够成功地做到这一点,但我还要检查这个特定λ值的VIF,以确保系数稳定并控制多重共线性。但我不知道如何检查GLMNET中的VIF,因为通常的vif()函数会抛出此错误。

vcov.default(mod)出错:   对于类elnet,glmnet

的模型,没有vcov()方法

请您帮我确认我的方法是否有任何问题或如何解决这个问题?

VIF不适用于GLMNET中的验证吗?

提前致谢。

4 个答案:

答案 0 :(得分:0)

VIF只是一组自变量的属性。只要它不改变非线性变量(例如加法模型那样),因为什么类型的因变量和使用的模型(线性回归,广义模型)并不重要。请参阅vif包中的car功能。因此,VIF应用于弹性网络回归,不会告诉您是否已处理多重共线性。它可以告诉你,有一个多重共线性来处理。

答案 1 :(得分:0)

通过实例的Hadi回归分析(p295)具有以下VIF的脊回归定义。 Z是协变量矩阵的标准化版本。

VIF for Ridge

答案 2 :(得分:0)

函数car::vif不适用于lm拟合产生的对象。您可能会从glmnet拟合中提取列名,并用lm重新拟合。然后在新版本上运行vif

此代码应该有效。

library(car)
library(glmnet)

cvfit <- cv.glmnet(train.x, train.y, 
                   family = "binomial", 
                   type.measure = "class", 
                   nlambda = 1000)

tmp_coeffs <- coef(cvfit, s = "lambda.min")
# get coef names
columns <- as.character(
                 data.frame(
                      name = tmp_coeffs@Dimnames[[1]][tmp_coeffs@i + 1],
                      coefficient = tmp_coeffs@x)[, 'name']
                      )

# create formula from fit
logistic_reduced <- as.formula(paste("outcome ~ ",
                                  paste(columns[-1], collapse = " + "),
                                  sep = ""))
# refit logistic
new.fit <- lm(logistic_reduced, 
              family=binomial(link='logit'), 
              data = train)

# get vif
vif(new.fit)

答案 3 :(得分:-1)

库:genridge 允许您拟合岭模型并计算模型参数的 vif。

document 也与此相关,请参阅第 13 页,其中详细解释了您可以进行的分析类型。

这是一个基于 genridge::vif.ridge 的例子。您可以将线性模型与岭回归进行比较,并绘制出 VIF 在使用更多正则化时如何下降。 有关更多示例,请参阅 ?vif.ridge

data(longley)
lmod <- lm(Employed ~ GNP + Unemployed + Armed.Forces + Population + 
             Year + GNP.deflator, data=longley)
vif(lmod)

longley.y <- longley[, "Employed"]
longley.X <- data.matrix(longley[, c(2:6,1)])

lambda <- c(0, 0.005, 0.01, 0.02, 0.04, 0.08)
lridge <- ridge(longley.y, longley.X, lambda=lambda)
coef(lridge)

vridge <- vif(lridge)
vridge

# plot VIFs
pch <- c(15:18, 7, 9)
clr <- c("black", rainbow(5, start=.6, end=.1))

matplot(rownames(vridge), vridge, type='b', 
        xlab='Ridge constant (k)', ylab="Variance Inflation", 
        xlim=c(0, 0.08), 
        col=clr, pch=pch, cex=1.2)
text(0.0, vridge[1,], colnames(vridge), pos=4)

enter image description here