R tidymodels 配方接近零方差过滤器的数值属性

问题描述

我在 R tidymodels 配方中使用 step_nzv 来过滤掉具有小方差但连续值的数字属性时遇到了麻烦。在我看来,该步骤仅适用于名义值,因为它计算唯一值的数量以及最常见与第二常见的比率。但是,我有一个属性,它几乎处处都接近于零,从不为零。我是否必须先装箱(并使用相同大小的箱进行离散化会改变一切)? 在下面的代码中,我有一个最小的例子。我希望这两个列 low_variance_num 和 low_variance_nom 都被过滤掉了,这不会发生:

library(tidymodels)

data <- tibble(num = seq(1000),rand = runif(1000)) %>% 
  mutate(low_variance_num = ifelse(num == 1,1,rand/10000),low_variance_nom = ifelse(num == 1,0))

data
var(data$low_variance_num)
var(data$low_variance_nom)

recipe <- recipe(formula = num ~.,data = data) %>% 
  update_role("num",new_role = "label") %>%
  step_nzv(all_predictors(),freq_cut = 995/5,unique_cut = 10) %>% # 5min bis hier
  prep()
summary(recipe)

P.S:有没有不提供公式就可以使用食谱的方法在这种情况下,公式是无稽之谈。

解决方法

对于初学者来说,是的,有一种方法可以在不提供公式的情况下使用食谱。为此,您只需将数据作为参数调用 recipe(),然后通过 update_role() 手动更新角色。当变量数量非常多时,这是推荐的方法,因为公式方法在变量很多时内存效率低下。

接下来,我想澄清一下what we mean in tidymodels by "nominal"

名义变量包括字符和因子。

全为 1 和 0 的数值变量不是在 tidymodels 中是名义变量(不会被 all_nominal() 等选择)。

接下来,我想指出,我认为 step_nzv() 不会做您希望的事情,因为您在不同意义上使用术语“方差”。如果您check out the docs,它描述了我们这里所说的接近零方差的含义:

例如,对于 1000 个样本,具有两个不同值且其中 999 个是单个值的近零方差预测器示例是这样的。

要被标记,首先,最普遍的值超过第二个最频繁的值的频率(称为“频率比”)必须高于 freq_cut。其次,“唯一值的百分比”,即唯一值的数量除以样本总数(乘以 100),也必须低于 unique_cut

根据此步骤中使用的定义,您制作的示例 low_variance_num 变量不是特别低;它有很多独特的价值。

作为参考,这里是如何在没有公式的情况下构建配方的演示:

library(recipes)
#> Loading required package: dplyr
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter,lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect,setdiff,setequal,union
#> 
#> Attaching package: 'recipes'
#> The following object is masked from 'package:stats':
#> 
#>     step

df <- tibble(num = seq(1000),rand = runif(1000)) %>% 
  mutate(pred1 = ifelse(num == 1,1,rand/10000),pred2 = ifelse(num == 1,0))

rec <- recipe(df) %>% 
  update_role(num,new_role = "label") %>%
  update_role(rand,pred1,pred2,new_role = "predictor") %>%
  step_nzv(all_predictors())

rec %>% prep() %>% bake(new_data = NULL)
#> # A tibble: 1,000 x 3
#>      num  rand     pred1
#>    <int> <dbl>     <dbl>
#>  1     1 0.842 1        
#>  2     2 0.942 0.0000942
#>  3     3 0.977 0.0000977
#>  4     4 0.595 0.0000595
#>  5     5 0.259 0.0000259
#>  6     6 0.454 0.0000454
#>  7     7 0.550 0.0000550
#>  8     8 0.388 0.0000388
#>  9     9 0.702 0.0000702
#> 10    10 0.481 0.0000481
#> # … with 990 more rows

reprex package (v0.3.0) 于 2021 年 1 月 7 日创建

预测变量 pred2 被移除,因为它的唯一值太少,而且它们几乎全为 0。预测变量 pred1 未被移除,因为它有许多唯一值。我想如果我想做您所描述的那种过滤,我会在数据清理/准备中进行,而不是在模型管道中的特征工程配方中进行。