Использование 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

объедините эти графики с помощью 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, ...) делают поезд на исходной задаче, а не на той, которая обновляется конвейером.


person ZchGarinch    schedule 10.03.2020    source источник


Ответы (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"))

должен сработать, если вызывается до передачи учащемуся.

person missuse    schedule 11.03.2020
comment
Спасибо, что нашли время ответить мне. Ваше решение работает для меня. Однако, используя cpoy или gunion, я хотел распараллелить предварительный процесс. Что вы порекомендуете для параллельной предварительной обработки, как мы можем делать с scikilearn pipeline? Благодарность - person ZchGarinch; 11.03.2020
comment
Рад, что могу помочь. Это другая тема. Я сомневаюсь, что в mlr3 распараллеливание осуществляется таким образом. И я сомневаюсь, что в этом случае вы бы извлекли из этого большую пользу, даже если бы это было так. Распараллеливание можно использовать, когда вы выполняете повторную выборку, когда каждый конвейер выполняется в каждой повторной выборке, а каждая повторная выборка выполняется в другом потоке. Я не думаю, что распараллеливание реализуется с помощью конвейера, если сопряженные пакеты не могут использовать его внутри. - person missuse; 11.03.2020
comment
И если я хочу делать мешки, используя gunion, изучая каждую модель, будет ли это параллельно? - person ZchGarinch; 11.03.2020
comment
Я предполагаю, что это так. Конвейер применяется к каждой подвыборке, и каждая подвыборка может выполняться в отдельном потоке. Но для окончательного вердикта я советую дождаться, пока один из членов команды mlr3 внесет свой вклад. - person missuse; 11.03.2020
comment
Я добавил ответ на ваш второй вопрос о том, как удалить категориальные переменные. - person missuse; 15.03.2020
comment
@FiesAtoS Решил ли мой ответ проблемы, которые вы указали в вопросе? - person missuse; 26.03.2020