3

I'm trying to tune a few models using instances, so there is a branching step with several models. I have the pipe constructed and works without models that require trafos. The parameters are set, and the dependencies work fine. I'm using trafos because I prefer to search over an exponential range rather than linear for some parameters. The trafos work before adding dependencies, but obviously the pipe cannot work without the dependencies. Adding the dependencies breaks the trafos.

Interestingly, in creating a reprex I realized the error doesn't require a task, pipe, etc, it occurs at the level of trafo/parameter set, but only when there's more than 1 learner in the pipe!

The error message is Error in exp(x$classif.svm.gamma) : non-numeric argument to mathematical function.

library(mlr3verse)

ps <- ParamSet$new(list(
  ParamFct$new("branch2.selection", levels = c('classif.rpart', 'classif.svm')),
  ParamDbl$new("classif.rpart.cp", lower = 0, upper = 0.05),
  ParamDbl$new("classif.svm.gamma", lower = -9L, upper = -5L),
  ParamInt$new("classif.svm.cost", lower = -2L, upper = 2L)
))

ps$trafo <- function(x, param_set) {
  x$classif.svm.cost = 2^(x$classif.svm.cost)
  x$classif.svm.gamma = exp(x$classif.svm.gamma)
  x
}

ps$add_dep("classif.rpart.cp", 'branch2.selection', CondEqual$new("classif.rpart"))

ps$add_dep("classif.svm.gamma", 'branch2.selection', CondEqual$new("classif.svm"))
ps$add_dep("classif.svm.cost", 'branch2.selection', CondEqual$new("classif.svm"))

generate_design_grid(ps, resolution = 6)
generate_design_grid(ps, resolution = 6)$transpose()

Again, the error only happens when there's more than one learner and therefore needs dependencies (it works with the branch/unbranch as long as it's the only learner), and it makes the grid just fine without the transpose() function.

I'm wondering if I need to code something differently for the trafo to function properly with a dependency.

1 Answers1

1

Sine you have dependencies, the parameters are not always active and therefore not present in x. You have to consider this in your trafo:

ps$trafo <- function(x, param_set) {
  if (!is.null(x$classif.svm.cost)) {
    x$classif.svm.cost = 2^(x$classif.svm.cost)
  }
  if (!is.null(x$classif.svm.gamma)) {
    x$classif.svm.gamma = exp(x$classif.svm.gamma)
  }
  x
}

One easy way to find this out is to set a breakpoint (or put browser()) into the trafo function and inspect x.

jakob-r
  • 6,824
  • 3
  • 29
  • 47
  • 1
    There are also the [`ps()` short forms](https://paradox.mlr-org.com/reference/ps.html) that take care of this. The given example would be `ps = ps(branch2.selection = p_fct(c('classif.rpart', 'classif.svm')), classif.rpart.cp = p_dbl(0, 0.05, depends = branch2.selection == "classif.rpart"), classif.svm.gamma = p_dbl(-9, -5, trafo = exp, depends = branch2.selection == "classif.svm"), classif.svm.cost = p_int(-2, 2, trafo = function(x) x^2, depends = branch2.selection == "classif.svm"))` and takes care of missing values in trafos automatically. – mb706 Mar 25 '21 at 12:05
  • I think you should post this as a separate solution :) – jakob-r Mar 25 '21 at 16:40