Python/GPyOpt: оптимизация только одного аргумента

В настоящее время я пытаюсь найти минимум некоторой функции f(arg1, arg2, arg3, ...) с помощью оптимизации по Гауссу, используя модуль GPyOpt. Хотя f(...) принимает много входных аргументов, я хочу оптимизировать только один из них. Как ты это делаешь?

Мое текущее «решение» состоит в том, чтобы поместить f(...) в фиктивный класс и указать неоптимизируемые аргументы при его инициализации. Хотя это, возможно, самый питоновский способ решения этой проблемы, он также намного сложнее, чем имеет право быть.

Краткий рабочий пример для функции f(x, y, method) с фиксированными y (числовым) и method (строка) при оптимизации 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)

Определенно должен быть более простой способ. Но все примеры, которые я нашел, оптимизируют все аргументы, и я не мог понять это, читая код на github (хотя я бы нашел информацию в GPyOpt.core.task.space , но не повезло).


person Leander Moesinger    schedule 30.07.2018    source источник


Ответы (2)


GPyOpt изначально поддерживает это с помощью контекста. Вы описываете всю область своей функции, а затем фиксируете значения некоторых переменных с помощью контекстного словаря при вызове процедуры оптимизации. API выглядит так:

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

Более подробную информацию можно найти в этом учебном блокноте про контекстную оптимизацию.

person Andrei    schedule 17.12.2018

Я бы проверил функцию partial из стандартной библиотеки functools. Это позволяет вам частично указать функцию, например:

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
)
person Theodore Ando    schedule 08.08.2018
comment
Определенно более чистый обходной путь, чем то, что я делал, но я все еще думаю, что должен быть способ напрямую указать это в объекте GPyOpt (исправление аргументов кажется слишком важным, чтобы требовать внешний модуль) - person Leander Moesinger; 09.08.2018
comment
Вы также можете просто добавить переменную типа discrete в свое пространство, например: {'name': 'y', 'type': 'discrete', 'domain': (2,)} - person Theodore Ando; 09.08.2018
comment
Это будет работать в этом конкретном примере, но, например. если функция принимает строку в качестве аргумента, это не сработает. Конечно, вы могли бы затем закодировать строку как целое число, но это снова очень беспорядочно. - person Leander Moesinger; 09.08.2018