使用 mlr3-pipelines 对数据进行插补和对因子列进行编码的 GraphLearner 方法?

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

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)

但是根据我选择的学习器,我遇到了几个错误。例如,如果我使用 ranger 作为学习器,我会遇到这个错误

Error: Missing data in columns: ....

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

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

1 – 我已经在每个图中使用了插补器,为什么有些算法仍然告诉我有缺失值?

2 – 如何在编码后移除分类变量?有些算法不支持这种类型的变量

更新

我认为在管道中进行的所有修改都没有被保存。换句话说,算法(svm, ranger, …)是在原始任务上进行训练,而不是在管道更新后的任务上


回答:

第一个问题的回答

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

让我们加载一堆包

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 

由于没有分类列,我将把 triceps 转换为一个:

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

当您在task上使用cat时:

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 %>>% scaleimp_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      48765:      neg 0.13341346 0.4693878  27     122 36.8    0.340        2      27766:      neg 0.11778846 0.4897959  30     121 26.2    0.245        5      23767:      pos 0.13341346 0.3673469  47     126 30.1    0.349        1      NA768:      neg 0.13341346 0.4693878  23      93 30.4    0.315        1      31

所以它在“insulin”和“pressure”列上做了它应该做的,但也返回了其他列未更改。

通过三次复制数据并在每个步骤中应用这三个预处理器,您返回了转换的列,但也返回了所有其他列 – 三次。

您应该做的是:

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

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

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注