【问题标题】:Computing importance measure using VIP package on a parsnip model在欧洲防风草模型上使用 VIP 包计算重要性度量
【发布时间】:2020-08-19 17:05:27
【问题描述】:

我正在尝试在欧洲防风草制作的逻辑回归模型上使用 vi_firm() 计算特征重要性。对于正则表达式,我将使用 iris 数据集并尝试预测观察结果是否为 setosa。

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')

这给了

错误:您的意思是使用new_data 而不是newdata

我还尝试使用相关 pdp 包中的部分生成部分依赖图。我得到同样的错误。

【问题讨论】:

    标签: r machine-learning tidymodels


    【解决方案1】:

    对于“glmnet”对象,正确的参数应该是s,而不是lambda,以便与coef.glmnet 保持一致(但是,由于与@ 部分匹配,当前使用vi() 调用它会产生错误987654327@ 参数---我将在本周末进行修复;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
    

    【讨论】:

      【解决方案2】:

      对于像 glmnet 这样的正则化模型,您可能希望坚持使用特定于模型的重要性分数(默认为 vi())。另外,请注意两件事:

      • 您需要指定要计算变量重要性的lambda 的哪个值(我只是在此示例中随机选择了一个)
      • 拟合的 glmnet 对象位于 iris_fit$fit 中,在 parsnip 对象内部
      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 创建

      【讨论】:

      • vi() 的输出似乎与 lambda 无关。无论 lambda 值如何,它都会生成相同的输出。这是否意味着这些 vi 不是特定于模型的?从@bgreenwell,如果我们使用vi_model(fit, s = iris_fit$fit$lambda[10]) 和选定的lambda,重要性值与来自glmnet 输出coef(fit,s = iris_fit$fit$lambda[10]) 的输出相匹配。我有点迷失在这里,感谢帮助澄清。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2020-09-24
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多