R中glmnet模型变重要性计算的不成熟性
我想计算R中glmnet模型的变量重要性。我使用R中glmnet模型变重要性计算的不成熟性,r,r-caret,glmnet,vip,R,R Caret,Glmnet,Vip,我想计算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.g
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")
这让我回过神来
># 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%之间
我知道
caret
软件包有varImp
函数,该函数提供0-100%之间的变量重要性。但是我想为cv.glmnet
对象实现同样的功能,而不是caret::train
对象。如何实现cv.glmnet
对象的变量重要性相似caret
包?问题是如何获得介于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]
}
为glmnet模型分配变量重要性的另一种方法是根据包含惩罚对变量进行评分——如果以较高惩罚排除变量,则变量更为重要。这种方法将在mlr3包中实施:在某一点上如果变量在某个λ上具有更高的系数,或者如果其系数在更高的L1惩罚下达到0,您会说变量更重要吗?我认为在某个λ上具有更高系数的变量,更重要。为什么不调用
vip::vi_model(cvfit.glmnet,s=cvfit.glmnet$lambda.min)
?与调用varImp(cvfit.glmnet,lambda=cvfit.glmnet$lambda.min)中一样
。我得到了相同的值,但差异varImp
返回了系数的绝对值。即使使用了vip::vi_模型(cvfit.glmnet,s=cvfit.glmnet$lambda.min)
,我只得到了不同的结果。你能用你得到的结果更新这个问题吗?非常感谢,您能提供您提到的使用mlr3
包的另一种方法吗?看起来我错了,它还没有实现:好的,函数varImp
基本上是从caret
包中获取的。虽然我们使用caret
package实现它,但是当我在问题中提到使用它时,它不提供缩放的重要性。你能告诉我为什么会发生这种情况吗?似乎对varImp函数的输出进行了额外的处理,在该函数中,对于所有在插入符号中有重要位置的学习者,它被缩放到0-1范围。考虑这些例子:<代码> CART::VALIMP(TestOrthCyrasCVY模型,lambda=0.007)和<代码> CART::VARIMP(TestOrthCythCVMask$FialMalm,lambda=0.007)< /Cord> >如果你在Gimple模型上调用它,你会得到不重要的重要性,而如果你调用这个火车对象,你会变得更重要。您可以通过插入符号:::varImp.train
#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
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