我想为R中的glmnet模型计算变量重要性。我正在使用glmnet
包来拟合弹性网模型,例如
library(glmnet)
library(caret)
library(vip)
data_y <- as.vector(mtcars$mpg)
data_x <- as.matrix(mtcars[-1])
fit.glmnet <- glmnet(data_x, data_y, family="gaussian")
set.seed(123)
cvfit.glmnet = cv.glmnet(data_x, data_y, standardize=T)
cvfit.glmnet$lambda.min
coef(cvfit.glmnet, s = "lambda.min")
然后我使用vip
软件包来作为具有不同重要性的软件包
#Using vip package
vip::vi_model(cvfit.glmnet, s = cvfit.glmnet$fit$lambda)
返回我
># A tibble: 10 x 3
Variable Importance Sign
<chr> <dbl> <chr>
1 cyl -0.886 NEG
2 disp 0 NEG
3 hp -0.0117 NEG
4 drat 0 NEG
5 wt -2.71 NEG
6 qsec 0 NEG
7 vs 0 NEG
8 am 0 NEG
9 gear 0 NEG
10 carb 0 NEG
变量重要性同时包含变量的正值和负值,其变化范围在0-1或0-100%之间。
然后我尝试使用此answer
的自定义功能#Using function provided in this example
varImp <- function(object, lambda = NULL, ...) {
## skipping a few lines
beta <- predict(object, s = lambda, type = "coef")
if(is.list(beta)) {
out <- do.call("cbind", lapply(beta, function(x) x[,1]))
out <- as.data.frame(out)
} else out <- data.frame(Overall = beta[,1])
out <- abs(out[rownames(out) != "(Intercept)",,drop = FALSE])
out
}
varImp(cvfit.glmnet, lambda = cvfit.glmnet$lambda.min)
它在输出后返回我
Overall
cyl 0.88608541
disp 0.00000000
hp 0.01168438
drat 0.00000000
wt 2.70814703
qsec 0.00000000
vs 0.00000000
am 0.00000000
gear 0.00000000
carb 0.00000000
尽管自定义函数的输出不包含负值,但它的变化范围是0-1或0-100%。
我知道caret
包具有varImp
功能,其重要性在0-100%之间变化。但是我想为cv.glmnet
对象而不是caret::train
对象实现相同的东西。如何为caret
对象的cv.glmnet
包实现可变重要性?
答案 0 :(得分:1)
问题询问如何获取0-100%之间的glmnet变量重要性。
如果希望基于系数幅度以某个(通常为最佳)惩罚来分配重要性。而且,如果这些系数是根据标准化变量(glmnet中的默认值)得出的,则这些系数可以简单地缩放到0-1范围:
给出了稍微修改的功能:
varImp <- function(object, lambda = NULL, ...) {
beta <- predict(object, s = lambda, type = "coef")
if(is.list(beta)) {
out <- do.call("cbind", lapply(beta, function(x) x[,1]))
out <- as.data.frame(out)
} else out <- data.frame(Overall = beta[,1])
out <- abs(out[rownames(out) != "(Intercept)",,drop = FALSE])
out <- out/max(out)
out[order(out$Overall, decreasing = TRUE),,drop=FALSE]
}
使用问题中的示例:
varImp(cvfit.glmnet, lambda = cvfit.glmnet$lambda.min)
#output
Overall
wt 1.000000000
cyl 0.320796270
am 0.004840186
hp 0.004605913
disp 0.000000000
drat 0.000000000
qsec 0.000000000
vs 0.000000000
gear 0.000000000
carb 0.000000000
将变量重要性分配给glmnet模型的另一种方法是根据包含的惩罚为变量评分-如果在较高的惩罚下排除变量,变量将更为重要。此方法将在mlr3软件包中实现:https://github.com/mlr-org/mlr3learners/issues/28在某些时候