вложенные ветви (и зависимости) в mlr3

#r #mlr3

#r #mlr3

Вопрос:

Я пытаюсь использовать фильтрацию функций information_gain и mrmr, а также комбинацию фильтрации функций information_gain и mrmr (объединение двух). Я попытался создать reprex ниже.

 library("mlr3verse")
task <- tsk('sonar')


filters = list("nop" = po("nop"),
               "information_gain" = po("filter", flt("information_gain")),
               "mrmr" = po("filter", flt("mrmr")),
               "ig_mrmr" = po("branch", c("ig2", "mrmr2"), id = "ig_mrmr") %>>%
                 gunion(list("ig2" = po("filter", flt("information_gain")),
                             "mrmr2" = po("filter", flt("mrmr")))) %>>%
                 po("featureunion", id = "union_igmrmr"))

pipe =
  po("branch", names(filters), id = "branch1") %>>%
  gunion(unname(filters)) %>>%
  po("unbranch", names(filters), id = "unbranch1") %>>%
  po(lrn('classif.rpart'))

pipe$plot()
 

график канала

Пока выглядит хорошо, и здесь вы можете видеть, что я пытаюсь объединить выбранные функции ig и mrmr.

Затем я устанавливаю параметры, которые я считаю правильными:

 ps <- ParamSet$new(list(
  ParamDbl$new("classif.rpart.cp", lower = 0, upper = 0.05),
  ParamInt$new("information_gain.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("information_gain.type", levels = c("infogain", "symuncert")),
  ParamInt$new("ig2.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("ig2.type", levels = c("infogain", "symuncert")),
  ParamInt$new("mrmr.filter.nfeat", lower = 20L, upper = 60L),
  ParamInt$new("mrmr2.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("branch1.selection", levels = names(filters)),
  ParamFct$new("ig_mrmr.selection", levels = c("ig2", "mrmr2"))
))
 

Зависимости — это то, с чем я борюсь. Я могу установить «вложенные» параметры ЛИБО для внешней, либо для внутренней ветви, но я не уверен, как их запускать для ОБЕИХ. В приведенном ниже примере они устанавливаются на внешней ветви.

 ps$add_dep("information_gain.filter.nfeat", "branch1.selection", CondEqual$new("information_gain"))
ps$add_dep("information_gain.type", "branch1.selection", CondEqual$new("information_gain"))
ps$add_dep("mrmr.filter.nfeat", "branch1.selection", CondEqual$new("mrmr"))
ps$add_dep("ig2.filter.nfeat", "branch1.selection", CondEqual$new("ig_mrmr"))
ps$add_dep("ig2.type", "branch1.selection", CondEqual$new("ig_mrmr"))
ps$add_dep("mrmr2.filter.nfeat", "branch1.selection", CondEqual$new("ig_mrmr"))

ps

glrn <- GraphLearner$new(pipe) 

glrn$predict_type <- "prob"

cv5 <- rsmp("cv", folds = 5)

task$col_roles$stratum <- task$target_names

instance <- TuningInstanceSingleCrit$new(
  task = task,
  learner = glrn,
  resampling = cv5,
  measure = msr("classif.auc"),
  search_space = ps,
  terminator = trm("evals", n_evals = 5)
)

tuner <- tnr("random_search")
tuner$optimize(instance)
 

Обратите внимание, что я не сталкиваюсь с ошибкой, пока не попытаюсь оптимизировать тюнер.

Сообщение об ошибке:

 Error in self$assert(xs) : 
  Assertion on 'xs' failed: Parameter 'ig2.filter.nfeat' not available. Did you mean 'branch1.selection' / 'information_gain.filter.nfeat' / 'information_gain.filter.frac'?.
 

Комментарии:

1. основываясь на вашем объяснении, я думаю, что вы не собираетесь использовать branch для «ig_mrmr», а скорее копировать. Ветвление выполняется тем или иным способом, если вы хотите, чтобы график выполнялся в обоих направлениях, а затем объединял результаты.

2. @missuse Это звучит возможно. В другом сегменте (не входит в состав reprex) Я использую «featureunion» для объединения PCA и необработанных данных (как в cbind (raw, pca)), поэтому я подумал, что это будет работать аналогично. Я в значительной степени основываю свой код на вашем примере, который я нашел от 20 января. Не могли бы вы предоставить фрагмент псевдокода, чтобы помочь мне начать?

3. @missuse Я попытался поменять местами `»ig_mrmr» = po («copy», 2) %>>%` для ветки и удалить пространство параметров для ветки, та же ошибка. Он не может найти параметры для ig2 и mrmr2, поэтому я думаю, что что-то не так с логикой в моих зависимостях.

Ответ №1:

Из вашего описания звучит так, как будто вы не собираетесь использовать ветку для c("ig2", "mrmr2") :

 po("branch", c("ig2", "mrmr2"), id = "ig_mrmr") %>>%
                 gunion(list("ig2" = po("filter", flt("information_gain")),
                             "mrmr2" = po("filter", flt("mrmr")))) %>>%
                 po("featureunion", id = "union_igmrmr")
 

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

 library("mlr3verse")
task <- tsk('sonar')
filters = list("nop" = po("nop"),
               "information_gain" = po("filter", flt("information_gain")),
               "mrmr" = po("filter", flt("mrmr")),
               "ig_mrmr" = po("copy", 2) %>>%
                 gunion(list("ig2" = po("filter", flt("information_gain")),
                                       "mrmr2" = po("filter", flt("mrmr")))) %>>%
                 po("featureunion", id = "union_igmrmr"))

pipe = po("branch", names(filters), id = "branch1") %>>%
  gunion(unname(filters)) %>>%
  po("unbranch", names(filters), id = "unbranch1") %>>%
  po(lrn('classif.rpart'))

pipe$plot()
 

введите описание изображения здесь

Самый простой способ увидеть параметры, которые вы можете настроить, это:

 pipe$param_set
 

Из этого вы увидите, что некоторые указанные вами параметры не имеют полных имен. Например:

 15:   ig2.information_gain.filter.nfeat ParamInt     0   Inf                                   <NoDefault[3]>      
16:    ig2.information_gain.filter.frac ParamDbl     0     1                                   <NoDefault[3]>      
17:  ig2.information_gain.filter.cutoff ParamDbl  -Inf   Inf                                   <NoDefault[3]>      
18:           ig2.information_gain.type ParamFct    NA    NA      infogain,gainratio,symuncert       infogain      
19:          ig2.information_gain.equal ParamLgl    NA    NA                        TRUE,FALSE          FALSE      
20:   ig2.information_gain.discIntegers ParamLgl    NA    NA                        TRUE,FALSE           TRUE      
21:        ig2.information_gain.threads ParamInt     0   Inf                                                1      
22: ig2.information_gain.affect_columns ParamUty    NA    NA                                    <Selector[1]>      
23:             mrmr2.mrmr.filter.nfeat ParamInt     0   Inf                                   <NoDefault[3]>      
24:              mrmr2.mrmr.filter.frac ParamDbl     0     1                                   <NoDefault[3]>      
25:            mrmr2.mrmr.filter.cutoff ParamDbl  -Inf   Inf                                   <NoDefault[3]>      
26:                  mrmr2.mrmr.threads ParamInt     0   Inf                                                0      
27:           mrmr2.mrmr.affect_columns ParamUty    NA    NA                                    <Selector[1]>      
 

Давайте зададим правильные имена для параметров:

 ps = ParamSet$new(list(
  ParamDbl$new("classif.rpart.cp", lower = 0, upper = 0.05),
  ParamInt$new("information_gain.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("information_gain.type", levels = c("infogain", "symuncert")),
  ParamInt$new("ig2.information_gain.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("ig2.information_gain.type", levels = c("infogain", "symuncert")),
  ParamInt$new("mrmr.filter.nfeat", lower = 20L, upper = 60L),
  ParamInt$new("mrmr2.mrmr.filter.nfeat", lower = 20L, upper = 60L),
  ParamFct$new("branch1.selection", levels = names(filters))
))

ps$add_dep("information_gain.filter.nfeat", "branch1.selection", CondEqual$new("information_gain"))
ps$add_dep("information_gain.type", "branch1.selection", CondEqual$new("information_gain"))
ps$add_dep("mrmr.filter.nfeat", "branch1.selection", CondEqual$new("mrmr"))
ps$add_dep("ig2.information_gain.filter.nfeat", "branch1.selection", CondEqual$new("ig_mrmr"))
ps$add_dep("ig2.information_gain.type", "branch1.selection", CondEqual$new("ig_mrmr"))
ps$add_dep("mrmr2.mrmr.filter.nfeat", "branch1.selection", CondEqual$new("ig_mrmr"))
 

и теперь все работает без проблем:

 glrn <- GraphLearner$new(pipe) 

glrn$predict_type <- "prob"

cv5 <- rsmp("cv", folds = 5)

task$col_roles$stratum <- task$target_names

instance <- TuningInstanceSingleCrit$new(
  task = task,
  learner = glrn,
  resampling = cv5,
  measure = msr("classif.auc"),
  search_space = ps,
  terminator = trm("evals", n_evals = 5)
)

tuner <- tnr("random_search")
tuner$optimize(instance)

instance$result
   classif.rpart.cp information_gain.filter.nfeat information_gain.type ig2.information_gain.filter.nfeat ig2.information_gain.type mrmr.filter.nfeat mrmr2.mrmr.filter.nfeat branch1.selection
1:       0.01956043                            NA                  <NA>                                44                 symuncert                NA                      34           ig_mrmr
   learner_param_vals  x_domain classif.auc
1:          <list[6]> <list[5]>   0.7187196
 

Этот пост в галерее будет полезен:

https://mlr3gallery.mlr-org.com/posts/2020-04-23-pipelines-selectors-branches/

а также другие

https://mlr3gallery.mlr-org.com/

Если вы чувствуете, что какой-то аспект mlr3 непонятен, и вы не можете найти подходящий пример публикации в галерее / книге, вам следует запросить его.

Ссылка на книгу: https://mlr3book.mlr-org.com /