requireNamespace("kknn")Loading required namespace: kknn
The website features runtime benchmarks of the paradox package now.
Optimize integer hyperparameters with tuners that can only propose real numbers.
Marc Becker
January 19, 2021
Tuner for real-valued search spaces are not able to tune on integer hyperparameters. However, it is possible to round the real values proposed by a Tuner to integers before passing them to the learner in the evaluation. We show how to apply a parameter transformation to a ParamSet and use this set in the tuning process.
We load the mlr3verse package which pulls in the most important packages for this example.
We initialize the random number generator with a fixed seed for reproducibility, and decrease the verbosity of the logger to keep the output clearly represented.
In this example, we use the k-Nearest-Neighbor classification learner. We want to tune the integer-valued hyperparameter k which defines the numbers of neighbors.
We choose generalized simulated annealing as tuning strategy. The param_classes field of TunerBatchGenSA states that the tuner only supports real-valued (ParamDbl) hyperparameter tuning.
── <TunerBatchGenSA>: Generalized Simulated Annealing ──────────────────────────────────────────────────────────────────
• Parameters: smooth=FALSE, maxit=2147483647, nb.stop.improvement=-1, max.call=2147483647
• Parameter classes: <ParamDbl>
• Properties: single-crit
• Packages: mlr3tuning, bbotk, and GenSA
To get integer-valued hyperparameter values for k, we construct a search space with a transformation function. The as.integer() function converts any real valued number to an integer by removing the decimal places.
We start the tuning and compare the results of the search space to the results in the space of the learners hyperparameter set.
Warning in optim(theta.old, fun, gradient, control = control, method = method, : one-dimensional optimization by Nelder-Mead is unreliable:
use "Brent" or optimize() directly
The optimal k is still a real number in the search space.
However, in the learners hyperparameters space, k is an integer value.
The archive shows us that for all real-valued k proposed by GenSA, an integer-valued k in the learner hyperparameter space was created.
k classif.ce
<num> <num>
1: 3.826860 0.06
2: 5.996323 0.06
3: 5.941332 0.06
4: 3.826860 0.06
5: 3.826860 0.06
6: 3.826860 0.06
7: 4.209546 0.06
8: 3.444174 0.06
9: 4.018203 0.06
10: 3.635517 0.06
11: 3.922532 0.06
12: 3.731189 0.06
13: 3.874696 0.06
14: 3.779024 0.06
15: 3.850778 0.06
16: 3.802942 0.06
17: 3.838819 0.06
18: 3.814901 0.06
19: 3.832840 0.06
20: 3.820881 0.06
k classif.ce
<num> <num>
Internally, TunerBatchGenSA was given the parameter types of the search space and therefore suggested real numbers for k. Before the performance of the different k values was evaluated, the transformation function of the search_space parameter set was called and k was transformed to an integer value.
Note that the tuner is not aware of the transformation. This has two problematic consequences: First, the tuner might propose different real valued configurations that after rounding end up to be already evaluated configurations and we end up with re-evaluating the same hyperparameter configuration. This is only problematic, if we only optimze integer parameters. Second, the rounding introduces discontinuities which can be problematic for some tuners.
We successfully tuned a integer-valued hyperparameter with TunerBatchGenSA which is only suitable for an real-valued search space. This technique is not limited to tuning problems. Optimizer in bbotk can be also used in the same way to produce points with integer parameters.
═ Session info ═══════════════════════════════════════════════════════════════════════════════════════════════════════
─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
backports 1.5.1 2026-04-03 [1] RSPM
base64url 1.4 2018-05-14 [1] RSPM
batchtools 0.9.18 2025-08-20 [1] RSPM
bbotk 1.13.1 2026-09-17 [1] RSPM
bit 4.6.0 2025-03-06 [1] RSPM
bit64 4.8.6 2026-09-01 [1] RSPM
brew 1.0-10 2023-12-16 [1] RSPM
callr 3.8.0 2026-06-05 [1] RSPM
checkmate 2.3.4 2026-02-03 [1] RSPM
class 7.3-24 2026-08-03 [2] CRAN (R 4.6.2)
classInt 0.4-11 2025-01-08 [1] RSPM
cli 3.6.6 2026-04-09 [1] RSPM
codetools 0.2-20 2024-03-31 [2] CRAN (R 4.6.2)
coro 1.1.0 2024-11-05 [1] RSPM
crayon 1.5.3 2024-06-20 [1] RSPM
data.table * 1.18.6.1 2026-08-24 [1] RSPM
DBI 1.3.0 2026-02-25 [1] RSPM
dictionar6 0.1.3 2026-02-23 [1] https://m~
digest 0.6.39 2025-11-19 [1] RSPM
distr6 1.8.4 2026-02-23 [1] https://m~
dplyr 1.2.1 2026-04-03 [1] RSPM
e1071 1.7-17 2025-12-18 [1] RSPM
evaluate 1.0.5 2025-08-27 [1] RSPM
farver 2.1.2 2024-05-13 [1] RSPM
fastmap 1.2.0 2024-05-15 [1] RSPM
future 1.82.0 2026-11-02 [1] RSPM
future.apply 1.21.0 2026-10-16 [1] RSPM
generics 0.1.4 2025-05-09 [1] RSPM
GenSA 1.1.15 2025-11-26 [1] RSPM
ggplot2 4.0.3 2026-04-22 [1] RSPM
globals 0.20.0 2026-10-11 [1] RSPM
glue 1.8.1 2026-04-17 [1] RSPM
gtable 0.3.6 2024-10-25 [1] RSPM
hms 1.1.4 2025-10-17 [1] RSPM
htmltools 0.5.9 2025-12-04 [1] RSPM
htmlwidgets 1.6.4 2023-12-06 [1] RSPM
igraph 2.3.4 2026-09-30 [1] RSPM
jsonlite 2.0.0 2025-03-27 [1] RSPM
KernSmooth 2.23-27 2026-08-12 [2] CRAN (R 4.6.2)
kknn 1.4.1 2025-05-19 [1] RSPM
knitr 1.52 2026-09-06 [1] RSPM
lattice 0.23-1 2026-08-12 [2] CRAN (R 4.6.2)
lgr 0.5.2 2026-01-30 [1] RSPM
lifecycle 1.0.5 2026-01-08 [1] RSPM
listenv 1.1.0 2026-10-04 [1] RSPM
magrittr 2.0.5 2026-04-04 [1] RSPM
Matrix 1.7-6 2026-07-25 [2] CRAN (R 4.6.2)
matrixStats 1.5.0 2025-01-07 [1] RSPM
mgcv 1.9-4 2025-11-07 [2] CRAN (R 4.6.2)
mlr3 * 1.8.0 2026-08-21 [1] RSPM
mlr3batchmark 0.2.2 2025-09-04 [1] RSPM
mlr3benchmark 0.1.8 2026-08-21 [1] RSPM
mlr3cluster 0.7.0 2026-10-17 [1] RSPM
mlr3cmprsk 0.0.7 2026-10-18 [1] https://m~
mlr3data 0.9.0 2024-11-08 [1] RSPM
mlr3db 0.7.3 2026-11-03 [1] RSPM
mlr3extralearners 1.7.0 2026-09-15 [1] https://m~
mlr3fairness 0.4.0 2026-11-04 [1] Github (mlr-org/mlr3fairness@6946cbe)
mlr3fda 0.7.2 2026-08-21 [1] RSPM
mlr3filters 0.9.1 2026-04-23 [1] RSPM
mlr3fselect 1.7.0 2026-08-23 [1] RSPM
mlr3hyperband 1.1.1 2026-07-25 [1] RSPM
mlr3inferr 0.2.2 2026-08-21 [1] RSPM
mlr3learners 0.16.0 2026-09-08 [1] RSPM
mlr3mbo 1.2.1 2026-07-26 [1] RSPM
mlr3measures 1.3.0 2026-04-17 [1] RSPM
mlr3misc 0.23.0 2026-08-21 [1] RSPM
mlr3oml 0.12.0 2026-01-28 [1] RSPM
mlr3pipelines 0.12.0 2026-09-05 [1] RSPM
mlr3proba 0.8.10 2026-06-05 [1] https://m~
mlr3spatial 0.7.0 2026-07-14 [1] RSPM
mlr3spatiotempcv 2.3.5 2026-08-03 [1] RSPM
mlr3torch 0.4.0 2026-10-30 [1] RSPM
mlr3tuning 1.7.0 2026-09-02 [1] RSPM
mlr3tuningspaces 0.7.0 2026-07-25 [1] RSPM
mlr3verse * 0.4.0 2026-09-15 [1] RSPM
mlr3viz 0.11.2 2026-09-23 [1] RSPM
mlr3website * 0.0.0.9000 2026-11-04 [1] Github (mlr-org/mlr3website@3087c0c)
moocore 0.3.2 2026-07-12 [1] RSPM
nlme 3.1-171 2026-09-01 [2] CRAN (R 4.6.2)
ooplah 0.2.0 2022-03-25 [1] https://m~
otel 0.2.0 2025-08-29 [1] RSPM
palmerpenguins 0.1.1 2022-08-15 [1] RSPM
paradox 1.0.1 2024-07-09 [1] RSPM
parallelly 1.50.0 2026-10-31 [1] RSPM
param6 0.2.4 2026-02-23 [1] https://m~
pillar 1.11.1 2025-09-17 [1] RSPM
pkgconfig 2.0.3 2019-09-22 [1] RSPM
prettyunits 1.2.0 2023-09-24 [1] RSPM
processx 3.9.0 2026-04-22 [1] RSPM
progress 1.2.3 2023-12-06 [1] RSPM
proxy 0.4-29 2025-12-29 [1] RSPM
ps 1.9.3 2026-04-20 [1] RSPM
purrr 1.2.2 2026-04-10 [1] RSPM
R6 2.6.1 2025-02-15 [1] RSPM
rappdirs 0.3.4 2026-01-17 [1] RSPM
rbibutils 2.4.1 2026-01-21 [1] RSPM
RColorBrewer 1.1-3 2022-04-03 [1] RSPM
Rcpp 1.1.2 2026-07-05 [1] RSPM
Rdpack 2.6.6 2026-02-08 [1] RSPM
rlang 1.3.0 2026-07-05 [1] RSPM
rmarkdown 2.32 2026-09-01 [1] RSPM
S7 0.2.2 2026-04-22 [1] RSPM
scales 1.4.0 2025-04-24 [1] RSPM
sessioninfo 1.2.4 2026-06-04 [1] RSPM
set6 0.2.6 2026-02-23 [1] https://m~
sf 1.1-3 2026-09-11 [1] RSPM
spacefillr 0.4.0 2025-02-24 [1] RSPM
stringi 1.8.9 2026-08-04 [1] RSPM
survival 3.8-12 2026-09-09 [2] CRAN (R 4.6.2)
terra 1.9-50 2026-09-08 [1] RSPM
tf 0.5.0 2026-07-14 [1] RSPM
tibble 3.3.1 2026-01-11 [1] RSPM
tidyselect 1.2.1 2024-03-11 [1] RSPM
torch 0.17.0 2026-04-11 [1] RSPM
units 1.0-1 2026-03-11 [1] RSPM
uuid 1.2-2 2026-01-23 [1] RSPM
vctrs 0.7.3 2026-04-11 [1] RSPM
withr 3.0.3 2026-06-19 [1] RSPM
xfun 0.62 2026-10-16 [1] RSPM
yaml 2.3.12 2025-12-10 [1] RSPM
zoo 1.9-1 2026-09-25 [1] RSPM
[1] /usr/local/lib/R/site-library
[2] /usr/local/lib/R/library
* ── Packages attached to the search path.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
---
title: Integer Hyperparameters in Tuners for Real-valued Search Spaces
categories:
- tuning
- classification
author:
- name: Marc Becker
description: |
Optimize integer hyperparameters with tuners that can only propose real numbers.
date: 01-19-2021
aliases:
- ../../../gallery/2021-01-19-integer-hyperparameters-in-tuners-for-real-valued-search-spaces/index.html
---
{{< include ../../_setup.qmd >}}
```{r index-001}
requireNamespace("kknn")
```
## Introduction
`r ref("Tuner")` for real-valued search spaces are not able to tune on integer hyperparameters.
However, it is possible to round the real values proposed by a `r ref("Tuner")` to integers before passing them to the learner in the evaluation.
We show how to apply a parameter transformation to a `r ref("ParamSet")` and use this set in the tuning process.
We load the `r ref_pkg("mlr3verse")` package which pulls in the most important packages for this example.
```{r index-002}
library(mlr3verse)
```
We initialize the random number generator with a fixed seed for reproducibility, and decrease the verbosity of the logger to keep the output clearly represented.
```{r index-003}
set.seed(7832)
lgr::get_logger("mlr3")$set_threshold("warn")
lgr::get_logger("bbotk")$set_threshold("warn")
```
## Task and Learner
In this example, we use the k-Nearest-Neighbor classification learner.
We want to tune the integer-valued hyperparameter `k` which defines the numbers of neighbors.
```{r index-004}
learner = lrn("classif.kknn")
learner$param_set$subset("k")
```
# Tuning
We choose generalized simulated annealing as tuning strategy.
The `param_classes` field of `r ref("TunerBatchGenSA")` states that the tuner only supports real-valued (`ParamDbl`) hyperparameter tuning.
```{r index-005}
print(tnr("gensa"))
```
To get integer-valued hyperparameter values for `k`, we construct a search space with a transformation function.
The `as.integer()` function converts any real valued number to an integer by removing the decimal places.
```{r index-006}
search_space = ps(
k = p_dbl(lower = 3, upper = 7.99, trafo = as.integer)
)
```
We start the tuning and compare the results of the search space to the results in the space of the learners hyperparameter set.
```{r index-007}
instance = tune(
tuner = tnr("gensa"),
task = tsk("iris"),
learner = learner,
resampling = rsmp("holdout"),
measure = msr("classif.ce"),
term_evals = 20,
search_space = search_space)
```
The optimal `k` is still a real number in the search space.
```{r index-008}
instance$result_x_search_space
```
However, in the learners hyperparameters space, `k` is an integer value.
```{r index-009}
instance$result_x_domain
```
The archive shows us that for all real-valued `k` proposed by `r ref_pkg("GenSA")`, an integer-valued `k` in the learner hyperparameter space was created.
```{r index-010}
as.data.table(instance$archive)[, .(k, classif.ce)]
```
Internally, `r ref("TunerBatchGenSA")` was given the parameter types of the search space and therefore suggested real numbers for `k`.
Before the performance of the different `k` values was evaluated, the transformation function of the `search_space` parameter set was called and `k` was transformed to an integer value.
Note that the tuner is not aware of the transformation.
This has two problematic consequences:
First, the tuner might propose different real valued configurations that after rounding end up to be already evaluated configurations and we end up with re-evaluating the same hyperparameter configuration.
This is only problematic, if we only optimze integer parameters.
Second, the rounding introduces discontinuities which can be problematic for some tuners.
We successfully tuned a integer-valued hyperparameter with `r ref("TunerBatchGenSA")` which is only suitable for an real-valued search space.
This technique is not limited to tuning problems.
`r ref("Optimizer")` in `r ref_pkg("bbotk")` can be also used in the same way to produce points with integer parameters.
{{< include ../../_session_info.qmd >}}