Использование mlr3-pipelines для вменения данных и кодирования факторных столбцов в GraphLearner?
У меня есть несколько вопросов по использованию 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
объедините эти графики по функциям Union 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, ...) делают поезд на исходной задаче, а не на той, которая обновляется конвейером.
1 ответ
Ответ на первый вопрос
Я постараюсь объяснить, почему в вашем рабочем процессе всегда отсутствуют значения.
позволяет загрузить кучу пакетов
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
Когда вы используете cat
на task
:
cat$train(task)[[1]]$data()
#big output
возвращаются не только столбцы, которые вы выбрали для преобразования, но и все остальные
Это также происходит для 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
Таким образом, он сделал то, что должен был делать с колонками "инсулин" и "давление", но также вернул остальное без изменений.
Копируя данные три раза и применяя эти три препроцессора на каждом шаге, вы возвращаете преобразованные столбцы, но также и все остальные - трижды.
Что вам следует сделать:
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"))
должен сработать, если был вызван до передачи учащемуся.