Использование mlr3-конвейеров для вменения данных и кодирования факторных столбцов в GraphLearner? - PullRequest
3 голосов
/ 10 марта 2020

У меня есть несколько вопросов относительно использования 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 - График для обработки подмножества числительных c переменных: среднее вменение => стандартизация

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

Третий график для обработки другого подмножества числительных c переменных: медианное вменение => минимальное максимальное масштабирование

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, gl mnet или xgvoost: у меня есть проблема из-за существования категорических переменные. Error : has the following unsupported feature types: factor...

С моим конвейером у меня не должно быть категориальной переменной и у меня не должно быть пропущенных значений. поэтому я не вижу, как решить эту проблему.

1 - Я использовал импутер в каждом графе, почему некоторые алгоритмы говорят мне, что всегда есть пропущенные значения?

2 - Как удалить категориальные переменные после их кодирования? некоторые алгоритмы не поддерживают переменные этого типа

Обновлено

Я думаю, что все изменения, сделанные во время конвейера, не сохраняются. Другими словами, алгоритмы (svm, ranger, ...) делают поезд на исходном задании, а не на обновленном конвейером

1 Ответ

1 голос
/ 11 марта 2020

Ответ на первый вопрос

Я попытаюсь объяснить, почему в вашем рабочем процессе всегда отсутствуют значения.

позволяет загрузить группу пакетов

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

, возвращаются не только выбранные вами столбцы для преобразования, но и все остальные

This происходит также для 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"))

должны сделать трюк, если он вызван до подачи в ученика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...