Python / GPyOpt: Optimizing only one argument

1k views Asked by At

I´m currently trying to find the minimum of some function f(arg1, arg2, arg3, ...) via Gaussian optimization using the GPyOpt module. While f(...) takes many input arguments, I only want to optimize a single one of them. How do you do that?

My current "solution" is to put f(...) in a dummy class and specify the not-to-be-optimized arguments while initializing it. While this is arguably the most pythonesque way of solving this problem, it`s also way more complicated than it has any right to be.

Short working example for a function f(x, y, method) with fixed y (a numeric) and method (a string) while optimizing x:

import GPyOpt
import numpy as np

# dummy class
class TarFun(object):
    # fix y while initializing the object
    def __init__(self, y, method):
        self.y = y
        self.method = method
    # actual function to be minimized
    def f(self, x):
        if self.method == 'sin':
            return np.sin(x-self.y)
        elif self.method == 'cos':
            return np.cos(x-self.y)

# create TarFun object with y fixed to 2 and use 'sin' method
tarFunObj = TarFun(y=2, method='sin')
# describe properties of x
space = [{'name':'x', 'type': 'continuous', 'domain': (-5,5)}]
# create GPyOpt object that will only optimize x
optObj = GPyOpt.methods.BayesianOptimization(tarFunObj.f, space)

There definitely has to be a simpler way. But all the examples I found optimize all arguments and I couldn't figure it out reading the code on github (I though i would find the information in GPyOpt.core.task.space , but had no luck).

2

There are 2 answers

0
Andrei On BEST ANSWER

GPyOpt supports this natively with context. You describe the whole domain of your function, and then fix values of some of the variables with a context dictionary when calling optimization routine. API looks like that:

myBopt.run_optimization(..., context={'var1': .3, 'var2': 0.4})

More details can be found in this tutorial notebook about contextual optimization.

3
Theodore Ando On

I would check out the partial function from the functools standard library. It allows you to partially specify a function, so for example:

import GPyOpt
import numpy as np
from functools import partial


def f(x, y=0):
    return np.sin(x - y)


objective = partial(f, y=2)
space = [{'name': 'x', 'type': 'continuous', 'domain': (-5, 5)}]

opt = GPyOpt.methods.BayesianOptimization(
    objective, domain=space
)