在防风草模型上使用 VIP 包计算重要性度量
Computing importance measure using VIP package on a parsnip model
我正在尝试使用 vi_firm() 在防风草制作的逻辑回归模型上计算特征重要性。对于正则表达式,我将使用鸢尾花数据集并尝试预测观察结果是否是山毛榉。
iris1 <- iris %>%
mutate(class = case_when(Species == 'setosa' ~ 'setosa',
TRUE ~ 'other'))
iris1$class = as.factor(iris1$class)
#set up logistic regression model
iris.lr = logistic_reg(
mode="classification",
penalty=NULL,
mixture=NULL
) %>%
set_engine("glmnet")
iris.fit = iris.lr %>%
fit(class ~. , data = iris1)
library(vip)
vip::vi_firm(iris.fit, feature_names = features, train = iris1, type = 'classification')
这给出了
Error: Did you mean to use new_data
instead of newdata
?
我也在尝试使用相关 pdp 包中的 partial 生成部分依赖图。我得到同样的错误。
对于适合 glmnet 的正则化模型,您可能希望坚持使用模型特定的重要性分数(默认值为 vi()
)。另外,请注意两件事:
- 您需要指定要计算变量重要性的
lambda
的哪个值(在此示例中我只是随机选择了一个值)
- 拟合的 glmnet 对象在
iris_fit$fit
中,在欧洲防风草对象的内部
library(tidymodels)
#> ── Attaching packages ────────────────────────────────────────── tidymodels 0.1.0 ──
#> ✓ broom 0.5.6 ✓ recipes 0.1.12
#> ✓ dials 0.0.6 ✓ rsample 0.0.6
#> ✓ dplyr 0.8.5 ✓ tibble 3.0.1
#> ✓ ggplot2 3.3.0 ✓ tune 0.1.0
#> ✓ infer 0.5.1 ✓ workflows 0.1.1
#> ✓ parsnip 0.1.1 ✓ yardstick 0.0.6
#> ✓ purrr 0.3.4
#> ── Conflicts ───────────────────────────────────────────── tidymodels_conflicts() ──
#> x purrr::discard() masks scales::discard()
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag() masks stats::lag()
#> x ggplot2::margin() masks dials::margin()
#> x recipes::step() masks stats::step()
iris1 <- iris %>%
mutate(class = case_when(Species == 'setosa' ~ 'setosa',
TRUE ~ 'other'),
class = factor(class)) %>%
select(-Species)
iris_mod <- logistic_reg(
penalty = NULL,
mixture = NULL
) %>%
set_engine("glmnet")
iris_fit <- iris_mod %>%
fit(class ~ ., data = iris1)
library(vip)
#>
#> Attaching package: 'vip'
#> The following object is masked from 'package:utils':
#>
#> vi
vi(iris_fit$fit,
lambda = iris_fit$fit$lambda[10])
#> # A tibble: 4 x 3
#> Variable Importance Sign
#> <chr> <dbl> <chr>
#> 1 Sepal.Width 3.35 POS
#> 2 Sepal.Length 0 NEG
#> 3 Petal.Width -2.97 NEG
#> 4 Petal.Length -3.98 NEG
由 reprex package (v0.3.0)
于 2020-05-14 创建
对于 "glmnet" 对象,正确的参数应该是 s
,而不是 lambda
,为了与 coef.glmnet
保持一致(但是,用 vi()
目前由于与 scale
参数的部分匹配而产生错误---我将在本周末推出修复;https://github.com/koalaverse/vip/issues/103)。此外,从版本 0.2.2 开始,vi_model 应该直接与 model_fit 对象一起使用。所以这里正确的调用应该是:
> vi_model(iris_fit, s = iris_fit$fit$lambda[10]). #
# A tibble: 4 x 3
Variable Importance Sign
<chr> <dbl> <chr>
1 Sepal.Length 0 NEG
2 Sepal.Width 0 NEG
3 Petal.Length -0.721 NEG
4 Petal.Width 0 NEG
就 vi_firm()
和 pdp::partial()
而言,最简单的方法是创建自己的预测包装器。每个函数的文档中应该有很多详细信息,我们即将发表的论文 (https://github.com/koalaverse/vip/blob/master/rjournal/RJwrapper.pdf) 中还有更多示例,但这里有一个基本示例:
> # Data matrix (features only)
> X <- data.matrix(subset(iris1, select = -class))
>
> # Prediction wrapper for partial dependence
> pfun <- function(object, newdata) {
+ # Return averaged prediciton for class of interest
+ mean(predict(object, newx = newdata, s = iris_fit$fit$lambda[10],
+ type = "link")[, 1L])
+ }
>
> # PDP-based VI
> features <- setdiff(names(iris1), "class")
> vip::vi_firm(
+ object = iris_fit$fit,
+ feature_names = features,
+ train = X,
+ pred.fun = pfun
+ )
# A tibble: 4 x 2
Variable Importance
<chr> <dbl>
1 Sepal.Length 0
2 Sepal.Width 0
3 Petal.Length 1.27
4 Petal.Width 0
>
> # PDP
> pd <- pdp::partial(iris_fit$fit, "Petal.Length", pred.fun = pfun,
+ train = X)
> head(pd)
Petal.Length yhat
1 1.000000 1.0644756
2 1.140476 0.9632228
3 1.280952 0.8619700
4 1.421429 0.7607172
5 1.561905 0.6594644
6 1.702381 0.5582116
我正在尝试使用 vi_firm() 在防风草制作的逻辑回归模型上计算特征重要性。对于正则表达式,我将使用鸢尾花数据集并尝试预测观察结果是否是山毛榉。
iris1 <- iris %>%
mutate(class = case_when(Species == 'setosa' ~ 'setosa',
TRUE ~ 'other'))
iris1$class = as.factor(iris1$class)
#set up logistic regression model
iris.lr = logistic_reg(
mode="classification",
penalty=NULL,
mixture=NULL
) %>%
set_engine("glmnet")
iris.fit = iris.lr %>%
fit(class ~. , data = iris1)
library(vip)
vip::vi_firm(iris.fit, feature_names = features, train = iris1, type = 'classification')
这给出了
Error: Did you mean to use
new_data
instead ofnewdata
?
我也在尝试使用相关 pdp 包中的 partial 生成部分依赖图。我得到同样的错误。
对于适合 glmnet 的正则化模型,您可能希望坚持使用模型特定的重要性分数(默认值为 vi()
)。另外,请注意两件事:
- 您需要指定要计算变量重要性的
lambda
的哪个值(在此示例中我只是随机选择了一个值) - 拟合的 glmnet 对象在
iris_fit$fit
中,在欧洲防风草对象的内部
library(tidymodels)
#> ── Attaching packages ────────────────────────────────────────── tidymodels 0.1.0 ──
#> ✓ broom 0.5.6 ✓ recipes 0.1.12
#> ✓ dials 0.0.6 ✓ rsample 0.0.6
#> ✓ dplyr 0.8.5 ✓ tibble 3.0.1
#> ✓ ggplot2 3.3.0 ✓ tune 0.1.0
#> ✓ infer 0.5.1 ✓ workflows 0.1.1
#> ✓ parsnip 0.1.1 ✓ yardstick 0.0.6
#> ✓ purrr 0.3.4
#> ── Conflicts ───────────────────────────────────────────── tidymodels_conflicts() ──
#> x purrr::discard() masks scales::discard()
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag() masks stats::lag()
#> x ggplot2::margin() masks dials::margin()
#> x recipes::step() masks stats::step()
iris1 <- iris %>%
mutate(class = case_when(Species == 'setosa' ~ 'setosa',
TRUE ~ 'other'),
class = factor(class)) %>%
select(-Species)
iris_mod <- logistic_reg(
penalty = NULL,
mixture = NULL
) %>%
set_engine("glmnet")
iris_fit <- iris_mod %>%
fit(class ~ ., data = iris1)
library(vip)
#>
#> Attaching package: 'vip'
#> The following object is masked from 'package:utils':
#>
#> vi
vi(iris_fit$fit,
lambda = iris_fit$fit$lambda[10])
#> # A tibble: 4 x 3
#> Variable Importance Sign
#> <chr> <dbl> <chr>
#> 1 Sepal.Width 3.35 POS
#> 2 Sepal.Length 0 NEG
#> 3 Petal.Width -2.97 NEG
#> 4 Petal.Length -3.98 NEG
由 reprex package (v0.3.0)
于 2020-05-14 创建对于 "glmnet" 对象,正确的参数应该是 s
,而不是 lambda
,为了与 coef.glmnet
保持一致(但是,用 vi()
目前由于与 scale
参数的部分匹配而产生错误---我将在本周末推出修复;https://github.com/koalaverse/vip/issues/103)。此外,从版本 0.2.2 开始,vi_model 应该直接与 model_fit 对象一起使用。所以这里正确的调用应该是:
> vi_model(iris_fit, s = iris_fit$fit$lambda[10]). #
# A tibble: 4 x 3
Variable Importance Sign
<chr> <dbl> <chr>
1 Sepal.Length 0 NEG
2 Sepal.Width 0 NEG
3 Petal.Length -0.721 NEG
4 Petal.Width 0 NEG
就 vi_firm()
和 pdp::partial()
而言,最简单的方法是创建自己的预测包装器。每个函数的文档中应该有很多详细信息,我们即将发表的论文 (https://github.com/koalaverse/vip/blob/master/rjournal/RJwrapper.pdf) 中还有更多示例,但这里有一个基本示例:
> # Data matrix (features only)
> X <- data.matrix(subset(iris1, select = -class))
>
> # Prediction wrapper for partial dependence
> pfun <- function(object, newdata) {
+ # Return averaged prediciton for class of interest
+ mean(predict(object, newx = newdata, s = iris_fit$fit$lambda[10],
+ type = "link")[, 1L])
+ }
>
> # PDP-based VI
> features <- setdiff(names(iris1), "class")
> vip::vi_firm(
+ object = iris_fit$fit,
+ feature_names = features,
+ train = X,
+ pred.fun = pfun
+ )
# A tibble: 4 x 2
Variable Importance
<chr> <dbl>
1 Sepal.Length 0
2 Sepal.Width 0
3 Petal.Length 1.27
4 Petal.Width 0
>
> # PDP
> pd <- pdp::partial(iris_fit$fit, "Petal.Length", pred.fun = pfun,
+ train = X)
> head(pd)
Petal.Length yhat
1 1.000000 1.0644756
2 1.140476 0.9632228
3 1.280952 0.8619700
4 1.421429 0.7607172
5 1.561905 0.6594644
6 1.702381 0.5582116