4

我有几个关于使用 mlr3-pipelines 的问题。事实上,我的目标是创建一个结合三个 3 图的管道:

1 - 处理分类变量的图表:水平插补 => 标准化

imp_cat     = po("imputenewlvl", param_vals =list(affect_columns = selector_name(my_cat_variables)))
encode      = po("encode",     param_vals =list(affect_columns = selector_name(my_cat_variables)))
cat = imp_cat %>>% encode

2 - 处理数值变量子集的图表: 均值插补 => 标准化

imp_mean = po("imputemean", param_vals = list(affect_columns =selector_name(my_first_set_of_numeric_variables)))
scale = po("scale", param_vals = list(affect_columns = selector_name(my_first_set_of_numeric_variables)))
num_mean = imp_mean %>>% scale

处理另一个数字变量子集的第三个图:中值估算 => 最小最大缩放

imp_median = po("imputemedian", param_vals = list(affect_columns =selector_name(my_second_set_of_numeric_variables)))
min_max = po("scalerange", param_vals = list(affect_columns = selector_name(my_second_set_of_numeric_variables)))
num_median = imp_median %>>% min_max

通过featureUnion Ops组合这些图表:

graph = po("copy", 3) %>>%
   gunion(list(cat, num_mean, num_median )) %>>%
   po("featureunion")

最后在 GraphLearner 中添加学习者:

g1 = GraphLearner$new(graph %>>% po(lrn("classif.ranger")))

我的数据中有一些缺失值,因此在每个图中都使用了插补器,并且我有一个二进制分类任务。

my_task = TaskClassif$new(id="classif", backend = data, target = "my_target")

从理论上讲,当我开始学习时,我不应该出现缺失值错误。

g1$train(my_task)

但根据我选择的学习者,我有几个错误。如果我使用例如游侠作为学习者:我有这个错误

Error: Missing data in columns: ....

如果我使用 svm、glmnet 或 xgvoost:由于存在分类变量,我遇到了问题。 Error : has the following unsupported feature types: factor...

使用我的管道,我不应该有分类变量,也不应该有缺失值。所以我不知道如何克服这个问题。

1 - 我在每个图中都使用了一个插补器,为什么有些算法告诉我总是有缺失值?

2 - 如何删除分类变量,一旦编码?一些算法不支持这种类型的变量

更新

我认为在管道期间所做的所有修改都不会保留。换句话说,算法(svm,ranger,...),使火车在原始任务上,而不是在由管道更新的任务上

4

1 回答 1

2

回答第一个问题

我将尝试解释为什么您的工作流程中总是缺少值。

让我们加载一堆包

library(mlr3) 
library(mlr3pipelines)
library(mlr3learners)
library(mlr3tuning)
library(paradox)

让我们接受缺少值的任务 pima

task <- tsk("pima")
task$missings()
diabetes      age  glucose  insulin     mass pedigree pregnant pressure  triceps 
       0        0        5      374       11        0        0       35      227 

由于没有分类列,我将三头肌转换为一个:

hb <- po("histbin",
         param_vals =list(affect_columns = selector_name("triceps")))

现在估算新级别并编码:

imp_cat <- po("imputenewlvl",
              param_vals =list(affect_columns = selector_name("triceps")))
encode <- po("encode",
             param_vals = list( affect_columns = selector_name("triceps")))

cat <- hb %>>% 
  imp_cat %>>%
  encode

当您cattask

cat$train(task)[[1]]$data()
#big output

不仅返回您选择转换的列,还返回所有其他列

这也发生在num_mediannum_mean上。

让我们创建它们

imp_mean <- po("imputemean", param_vals = list(affect_columns = selector_name(c("glucose", "mass"))))
scale <- po("scale", param_vals = list(affect_columns = selector_name(c("glucose", "mass"))))
num_mean <- imp_mean %>>% scale


imp_median <- po("imputemedian", param_vals = list(affect_columns = selector_name(c("insulin", "pressure"))))
min_max <- po("scalerange", param_vals = list(affect_columns = selector_name(c("insulin", "pressure"))))
num_median <- imp_median %>>% min_max

检查num_median什么

num_median$train(task)[[1]]$data()
#output
     diabetes    insulin  pressure age glucose mass pedigree pregnant triceps
  1:      pos 0.13341346 0.4897959  50     148 33.6    0.627        6      35
  2:      neg 0.13341346 0.4285714  31      85 26.6    0.351        1      29
  3:      pos 0.13341346 0.4081633  32     183 23.3    0.672        8      NA
  4:      neg 0.09615385 0.4285714  21      89 28.1    0.167        1      23
  5:      pos 0.18509615 0.1632653  33     137 43.1    2.288        0      35
 ---                                                                         
764:      neg 0.19951923 0.5306122  63     101 32.9    0.171       10      48
765:      neg 0.13341346 0.4693878  27     122 36.8    0.340        2      27
766:      neg 0.11778846 0.4897959  30     121 26.2    0.245        5      23
767:      pos 0.13341346 0.3673469  47     126 30.1    0.349        1      NA
768:      neg 0.13341346 0.4693878  23      93 30.4    0.315        1      31

所以它在“胰岛素”和“压力”列上做了它应该做的事情,但也没有改变其余部分。

通过复制数据三次并在每个步骤中应用这三个预处理器,您可以返回转换后的列,还返回所有其余的列 - 三次。

你应该做的是:

graph <- cat %>>%
  num_mean %>>%
  num_median

cat转换选定的列并返回所有,然后num_mean 转换选定的列并返回所有...

graph$train(task)[[1]]$data()

在我看来很好

更重要的是

g1 <- GraphLearner$new(graph %>>% po(lrn("classif.ranger")))
g1$train(task)

作品

2 - 第二个问题的答案是使用选择器功能,特别是在您的情况下

selector_type()

selector_invert(selector_type("factor"))

如果在导入学习器之前调用它应该可以解决问题。

于 2020-03-11T11:40:15.587 回答