rhyperparametersmlr

In MLR, How to set Logical Hyperparameter to either TRUE or FALSE only?


I have this dataset to try to make a classification task using classif.ada

library(mlr)
data("HouseVotes84")
#Using HouseVotes84 as Classification Task Dataset and mtcars as Regression Task Dataset
dummy_data_classif <- HouseVotes84[,2:length(colnames(HouseVotes84))] %>% 
  mutate_if(is.factor, as.numeric)
dummy_data_classif <- data.frame(cbind(Class=HouseVotes84[,1], dummy_data_classif))
dummy_data_classif[is.na(dummy_data_classif)] <- 0
dummy_data_classif_numeric <- dummy_data_classif[-1] %>%
  mutate_if(is.factor, as.numeric)
dummy_data_classif_numeric <- data.frame(cbind(dummy_data_classif[1], 
                                               dummy_data_classif_numeric))
colnames(dummy_data_classif_numeric) <- colnames(dummy_data_classif)

and I have this parameter expression in string that will be evaluate later for classif.ada param set in MLR

param_to_eval

"hyperparam <<- makeParamSet(
makeIntegerParam(\"iter\",lower = 50,upper=250), 
makeIntegerParam(\"max.iter\",lower = 30,upper=200), 
makeLogicalParam(\"model.coef\",FALSE, tunable=FALSE), 
makeDiscreteParam(\"loss\",values = c(\"exponential\", \"logistic\")), 
makeDiscreteParam(\"type\",values = c(\"discrete\", \"real\", \"gentle\")), 
makeNumericParam(\"nu\",lower = 0,upper=100), 
makeNumericParam(\"bag.frac\",lower = 0,upper=1), 
makeLogicalParam(\"bag.shift\"), 
makeNumericParam(\"delta\",lower = 0,upper=1e-07), 
makeIntegerParam(\"minsplit\",lower = 1,upper=30), 
makeIntegerParam(\"minbucket\",lower = 1,upper=20), 
makeNumericParam(\"cp\",lower = 0,upper=1), 
makeIntegerParam(\"maxcompete\",lower = 0,upper=6), 
makeIntegerParam(\"maxsurrogate\",lower = 0,upper=7.5), 
makeDiscreteParam(\"usesurrogate\",values = c(0, 1, 2)), 
makeDiscreteParam(\"surrogatestyle\",values = c(0, 1)), 
makeIntegerParam(\"maxdepth\",lower = 1,upper=30))"

Then I defined tasking for classif.ada, and planned for tuning 20 random param sets

task <- makeClassifTask(data = dummy_data_classif_numeric, 
                        target = "Class")
lrn <- makeLearner(cl = "classif.ada", fix.factors.prediction = TRUE)
eval(parse(text=param_to_eval)) 

hyper_search <- makeTuneControlRandom(maxit = 20)
resampling_method <- makeResampleDesc("cv")
    
# Perform tuning
lrn_tune <- tuneParams(learner = "classif.ada", task = task, 
                       resampling = resampling_method, 
                       control = hyper_search, par.set = hyperparam)

In these examples, I want the "model.coef" hyperparameter to only contain FALSE value to tune, After running these, model.coef is still tuned between TRUE and FALSE and getting this error:

[Tune] Started tuning learner classif.ada for parameter set:
                   Type len   Def               Constr Req Tunable Trafo
iter            integer   -     -            50 to 250   -    TRUE     -
max.iter        integer   -     -            30 to 200   -    TRUE     -
model.coef      logical   - FALSE                    -   -   FALSE     -
loss           discrete   -     - exponential,logistic   -    TRUE     -
type           discrete   -     - discrete,real,gentle   -    TRUE     -
nu              numeric   -     -             0 to 100   -    TRUE     -
bag.frac        numeric   -     -               0 to 1   -    TRUE     -
bag.shift       logical   -     -                    -   -    TRUE     -
delta           numeric   -     -           0 to 1e-07   -    TRUE     -
minsplit        integer   -     -              1 to 30   -    TRUE     -
minbucket       integer   -     -              1 to 20   -    TRUE     -
cp              numeric   -     -               0 to 1   -    TRUE     -
maxcompete      integer   -     -               0 to 6   -    TRUE     -
maxsurrogate    integer   -     -             0 to 7.5   -    TRUE     -
usesurrogate   discrete   -     -                0,1,2   -    TRUE     -
surrogatestyle discrete   -     -                  0,1   -    TRUE     -
maxdepth        integer   -     -              1 to 30   -    TRUE     -
With control class: TuneControlRandom
Imputation value: 1
[Tune-x] 1: iter=233; max.iter=141; model.coef=FALSE; loss=exponential; type=gentle; nu=63.5; bag.frac=0.686; bag.shift=TRUE; delta=3.49e-08; minsplit=21; minbucket=2; cp=0.881; maxcompete=1; maxsurrogate=2; usesurrogate=2; surrogatestyle=0; maxdepth=17
[Tune-y] 1: mmce.test.mean=0.0598309; time: 0.8 min
[Tune-x] 2: iter=230; max.iter=115; model.coef=TRUE; loss=exponential; type=gentle; nu=39.6; bag.frac=0.35; bag.shift=TRUE; delta=4.87e-08; minsplit=1; minbucket=2; cp=0.523; maxcompete=4; maxsurrogate=7; usesurrogate=0; surrogatestyle=1; maxdepth=21
Error in if (any(wt < 0)) stop("negative weights not allowed") : 
  missing value where TRUE/FALSE needed
In addition: Warning message:
In log((1 - errm)/errm) :
 Error in if (any(wt < 0)) stop("negative weights not allowed") : 
  missing value where TRUE/FALSE needed 

How to make "model.coef" contain FALSE only?


Solution

  • If you want one value to be fixed and not included in the search space you have to set the value of this parameter manually and exclude it form the search space:

    hyperparam$pars$model.coef = NULL
    learner <- makeLearner("classif.ada", par.vals = list(model.coef = FALSE))
    lrn_tune <- tuneParams(learner = learner, task = task, 
                           resampling = resampling_method, 
                           control = hyper_search, par.set = hyperparam)
    

    It makes more sense to leave out model.coef in the definition of the search space (hyperparam object) directly, but your example looks like you somehow have the object predefined.