-
-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathmlrMBO.Rmd
More file actions
161 lines (115 loc) · 5.89 KB
/
mlrMBO.Rmd
File metadata and controls
161 lines (115 loc) · 5.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
---
title: "mlrMBO: A brief introduction"
vignette: >
%\VignetteIndexEntry{Quick introduction}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE, cache = FALSE}
library(mlrMBO)
library(rgenoud)
set.seed(123)
knitr::opts_chunk$set(cache = TRUE, collapse = FALSE)
knitr::knit_hooks$set(document = function(x){
gsub("```\n*```r*\n*", "", x)
})
```
# Overview
The main goal of `mlrMBO` is to optimize *expensive black-box functions* by *model-based optimization* (aka Bayesian optimization) and to provide a unified interface for different optimization tasks and algorithmic MBO variants.
Supported are, among other things:
- Efficient global optimization (EGO) of problems with numerical domain and Kriging as surrogate
- Using arbitrary regression models from [mlr](https://github.com/mlr-org/mlr/) as surrogates
- Built-in parallelization using multi-point proposals
- Mixed-space optimization with categorical and subordinate parameters, for parameter configuration and tuning
- Multi-criteria optimization
This vignette gives a brief overview of the features of `mlrMBO`.
A more detailed documentation can be found on: <https://mlrmbo.mlr-org.com/>.
# Quickstart
## Prerequisites
Installing `mlrMBO` will also install and load the dependencies `mlr`, `ParamHelpers`, and `smoof`.
For this tutorial, you also need the additional packages `DiceKriging` and `randomForest`.
```{r load_package}
library(mlrMBO)
```
## General MBO workflow
1. Define **objective function** and its parameters using the package `smoof`.
2. Generate **initial design** (optional).
3. Define `mlr` learner for **surrogate model** (optional).
4. Set up a **MBO control** object.
5. Start the optimization with `mbo()`.
As a simple example we minimize a cosine-like function with an initial design of 5 points and 10 sequential MBO iterations.
Thus, the optimizer is allowed 15 evaluations of the objective function in total to approximate the optimum.
### Objective Function
Instead of manually defining the objective, we use the [*smoof*](https://cran.r-project.org/package=smoof) package which offers many toy and benchmark functions for optimization.
```{r cosine_fun}
obj.fun = makeCosineMixtureFunction(1)
obj.fun = convertToMinimization(obj.fun)
print(obj.fun)
ggplot2::autoplot(obj.fun)
```
You are not limited to these test functions but can define arbitrary objective functions with *smoof*.
```{r smoof_custom_objective}
makeSingleObjectiveFunction(
name = "my_sphere",
fn = function(x) {
sum(x*x) + 7
},
par.set = makeParamSet(
makeNumericVectorParam("x", len = 2L, lower = -5, upper = 5)
),
minimize = TRUE
)
```
Check `?smoof::makeSingleObjectiveFunction` for further details.
### Initial Design
Before MBO can really start, it needs a set of already evaluated points - the *inital design*, as we have to initially learn our first machine learning regression model to propose new points for evaluation.
If no design is given (i.e. `design = NULL`), `mbo()` will use a *Maximin Latin Hypercube* `lhs::maximinLHS()` design with `n = 4 * getNumberOfParameters(obj.fun)` points.
If the design does not include function outcomes `mbo()` will evaluate the design first before starting with the MBO algorithm.
In this example we generate our own design.
```{r}
des = generateDesign(n = 5, par.set = getParamSet(obj.fun), fun = lhs::randomLHS)
```
We will also precalculate the results:
```{r}
des$y = apply(des, 1, obj.fun)
```
_Note:_ *mlrMBO* uses `y` as a default name for the outcome of the objective function.
This can be changed in the control object.
### Surrogate Model
We decide to use Kriging as our surrogate model because it has proven to be quite effective for numerical domains.
The surrogate must be specified as a mlr regression learner:
```{r}
surr.km = makeLearner("regr.km", predict.type = "se", covtype = "matern3_2", control = list(trace = FALSE))
```
_Note:_ If no surrogate learner is defined, `mbo()` automatically uses Kriging for a numerical domain, otherwise *random forest regression*.
### MBOControl
The `MBOControl` object allows customization of the optimization run and algorithmic behavior of MBO.
It is created with `makeMBOControl()`, and can be modified with further setter-functions.
For further customization there are the following functions:
* `setMBOControlTermination()`: It is obligatory to define a termination criterion like the number of MBO iterations.
* `setMBOControlInfill()`: It is recommended to set the infill criterion. For learners that support `predict.type = "se"` the Confidence Bound `"cb"` and the Expected Improvement `"ei"` are a good choice.
* `setMBOControlMultiPoint()`: Needed, in case you want to evaluate more then just one point per MBO-Iteration you can control this process here. This makes sense for parallelization.
* `setMBOControlMultiObj()`: Needed, in case you want to optimize a multi-objective target function.
```{r cosine_setup}
control = makeMBOControl()
control = setMBOControlTermination(control, iters = 10)
control = setMBOControlInfill(control, crit = makeMBOInfillCritEI())
```
### Start the optimization
Finally, we start the optimization process and print the result object.
It contains the best best found solution and its corresponding objective value.
```{r cosine_run, results='hold'}
run = mbo(obj.fun, design = des, learner = surr.km, control = control, show.info = TRUE)
print(run)
```
## Visualization
For more insights into the MBO process, we can also start the previous optimization with the function `exampleRun()` instead of `mbo()`.
This augments the results of `mbo()` with additional information for plotting.
Here, we plot the optimization state at iterations 1, 2, and 10.
```{r cosine_examplerun, results="hide"}
run = exampleRun(obj.fun, learner = surr.km, control = control, show.info = FALSE)
```
```{r cosine_plot_examplerun, warning=FALSE}
print(run)
plotExampleRun(run, iters = c(1L, 2L, 10L), pause = FALSE)
```