Bayesian optimization with context variables

In this notebook we are going to see how to use Emukit to solve optimization problems in which certain variables are fixed during the optimization phase. These are called context variables [1]. This is useful when some of the variables in the optimization are controllable/known factors. And example is the optimization of a the movement of a robot under conditions of the environment change (but the change is known).

In [12]:
from emukit.test_functions import branin_function
from emukit.core import ParameterSpace, ContinuousParameter, DiscreteParameter
from emukit.experimental_design.model_free.random_design import RandomDesign
from GPy.models import GPRegression
from emukit.model_wrappers import GPyModelWrapper
from emukit.bayesian_optimization.acquisitions import ExpectedImprovement
from emukit.bayesian_optimization.loops import BayesianOptimizationLoop
from emukit.core.loop import FixedIterationsStoppingCondition

Loading the problem and the loop

In [13]:
f, parameter_space = branin_function()

Now we define the domain of the function to optimize.

We build the model:

In [20]:
design = RandomDesign(parameter_space) # Collect random points
X = design.get_samples(10)
Y = f(X)
model_gpy = GPRegression(X,Y) # Train and wrap the model in Emukit
model_emukit = GPyModelWrapper(model_gpy)

And prepare the optimization object to run the loop.

In [21]:
expected_improvement = ExpectedImprovement(model = model_emukit)
bayesopt_loop = BayesianOptimizationLoop(model = model_emukit,
                                         space = parameter_space,
                                         acquisition = expected_improvement,
                                         batch_size = 1)

Now, we set the number of iterations to run to 10.

In [22]:
max_iter = 10

Running the optimization by setting a context variable

To set a context, we just need to create a dictionary with the variables to fix and pass it to the Bayesian optimization object when running the optimization. Note that, every time we run new iterations we can set other variables to be the context. We run 3 sequences of 10 iterations each with different values of the context.

In [23]:
bayesopt_loop.run_loop(f, max_iter, context={'x1':0.3}) # we set x1 as the context variable
bayesopt_loop.run_loop(f, max_iter, context={'x2':0.1}) # we set x2 as the context variable
bayesopt_loop.run_loop(f, max_iter) # no context
Optimization restart 1/1, f = 55.82239092951151
Optimization restart 1/1, f = 61.3846273395993
Optimization restart 1/1, f = 65.9026092044098
Optimization restart 1/1, f = 70.10888667806952
Optimization restart 1/1, f = 74.1328973094729
Optimization restart 1/1, f = 77.99175645392145
Optimization restart 1/1, f = 52.29992606115588
Optimization restart 1/1, f = 57.2135370696718
Optimization restart 1/1, f = 61.71269586013616
Optimization restart 1/1, f = 64.61711212283623
Optimization restart 1/1, f = 67.32871572150273
Optimization restart 1/1, f = 67.32871572150273
Optimization restart 1/1, f = 72.46948949054092
Optimization restart 1/1, f = 76.3396222448238
Optimization restart 1/1, f = 80.13694597576568
Optimization restart 1/1, f = 82.78050118466332
Optimization restart 1/1, f = 85.53554907845636
Optimization restart 1/1, f = 87.66997139826
Optimization restart 1/1, f = 82.51513223264337
Optimization restart 1/1, f = 74.56925204657252
Optimization restart 1/1, f = 66.47734698335717
Optimization restart 1/1, f = 58.330733958274834
Optimization restart 1/1, f = 58.330733958274834
Optimization restart 1/1, f = 64.60067656071124
Optimization restart 1/1, f = 70.20437602983576
Optimization restart 1/1, f = 75.80428915860006
Optimization restart 1/1, f = 80.95909118096986
Optimization restart 1/1, f = 85.034596272839
Optimization restart 1/1, f = 89.12568615232692
Optimization restart 1/1, f = 92.23693057747008
Optimization restart 1/1, f = 97.40863200244975
Optimization restart 1/1, f = 102.46737266911367
Optimization restart 1/1, f = 106.5758265632924

We can now inspect the collected points.

In [24]:
bayesopt_loop.loop_state.X
Out[24]:
array([[-2.86743881,  3.59367664],
       [-0.8549767 ,  4.35170154],
       [-4.19297718,  5.75740955],
       [ 4.09539566,  9.60446259],
       [-1.1567395 ,  9.34152556],
       [-4.78218511,  1.6005059 ],
       [ 9.81108434,  0.68328574],
       [-3.38000907,  7.03298957],
       [ 2.24030232,  1.75291367],
       [ 2.59017018,  7.90703187],
       [ 0.3       , 15.        ],
       [ 0.3       ,  5.9568478 ],
       [ 0.3       ,  6.0418334 ],
       [ 0.3       ,  6.02940932],
       [ 0.3       ,  5.96593168],
       [ 0.3       ,  5.79749794],
       [ 0.3       ,  0.        ],
       [ 0.3       , 11.39503045],
       [ 0.3       ,  2.05768221],
       [ 0.3       , 13.31713269],
       [ 6.27026404,  0.1       ],
       [10.        ,  0.1       ],
       [ 3.8018847 ,  0.1       ],
       [ 4.24030648,  0.1       ],
       [ 3.23298497,  0.1       ],
       [ 9.03660343,  0.1       ],
       [ 3.43316197,  0.1       ],
       [ 3.43169522,  0.1       ],
       [ 3.42251264,  0.1       ],
       [ 3.43341329,  0.1       ],
       [10.        , 15.        ],
       [10.        ,  6.17855086],
       [-5.        , 12.67836313],
       [ 5.73368901,  4.73475117],
       [10.        ,  3.76300377],
       [-3.81429212, 10.31416342],
       [ 3.09393687,  4.05391353],
       [-4.2297243 , 15.        ],
       [10.        , 10.01932978],
       [-2.99896834, 13.20862014]])

References

  • [1] Krause, A. & Ong, C. S. Contextual gaussian process bandit optimization Advances in Neural Information Processing Systems (NIPS), 2011, 2447-2455*