使用 mlr3-pipelines 在 GraphLearner 中估算数据和编码因子列?
Using mlr3-pipelines to impute data and encode factor columns in GraphLearner?
我有几个关于 mlr3 管道使用的问题。事实上,我的目标是创建一个结合了三个 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,......),使火车在原始任务上,而不是在管道更新的任务上
第一个问题的答案
我将尝试解释为什么您的工作流程中总是缺少值。
让我们加载一堆包
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
当您在 task
上使用 cat
时:
cat$train(task)[[1]]$data()
#big output
不仅 return 编辑了您选择要转换的列,而且还编辑了所有其他列
num_median
和 num_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
所以它在 "insulin" 和 "pressure" 列上做了它应该做的事情,但 return 其余部分没有改变。
通过将数据复制三次并在每个步骤中应用这三个预处理器,您可以 return 转换列以及所有其余列 - 三次。
你应该做的是:
graph <- cat %>>%
num_mean %>>%
num_median
cat
转换选定的列和 return 全部,然后 num_mean
转换选定的列和 return 全部...
graph$train(task)[[1]]$data()
我觉得不错
更重要的是
g1 <- GraphLearner$new(graph %>>% po(lrn("classif.ranger")))
g1$train(task)
有效
2 - 第二个问题的答案是使用 selector functions,特别是在你的情况下
selector_type()
:
selector_invert(selector_type("factor"))
如果在进入学习器之前调用,应该可以做到这一点。
我有几个关于 mlr3 管道使用的问题。事实上,我的目标是创建一个结合了三个 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,......),使火车在原始任务上,而不是在管道更新的任务上
第一个问题的答案
我将尝试解释为什么您的工作流程中总是缺少值。
让我们加载一堆包
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
当您在 task
上使用 cat
时:
cat$train(task)[[1]]$data()
#big output
不仅 return 编辑了您选择要转换的列,而且还编辑了所有其他列
num_median
和 num_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
所以它在 "insulin" 和 "pressure" 列上做了它应该做的事情,但 return 其余部分没有改变。
通过将数据复制三次并在每个步骤中应用这三个预处理器,您可以 return 转换列以及所有其余列 - 三次。
你应该做的是:
graph <- cat %>>%
num_mean %>>%
num_median
cat
转换选定的列和 return 全部,然后 num_mean
转换选定的列和 return 全部...
graph$train(task)[[1]]$data()
我觉得不错
更重要的是
g1 <- GraphLearner$new(graph %>>% po(lrn("classif.ranger")))
g1$train(task)
有效
2 - 第二个问题的答案是使用 selector functions,特别是在你的情况下
selector_type()
:
selector_invert(selector_type("factor"))
如果在进入学习器之前调用,应该可以做到这一点。