Оптимизация и линейные неравенства с Mystic - PullRequest
0 голосов
/ 05 января 2019

Я работаю с довольно сложной целевой функцией, которую я минимизирую, изменяя 4 параметра. Некоторое время назад я решил использовать платформу Python Mystic , которая позволяет мне использовать штрафы за сложные неравенства (которые мне нужны).

Тем не менее, Mystic имеет менее очевидный способ назначения жестких ограничений (не неравенств и не связанных ограничений, линейных неравенств только между параметрами) и даже менее очевидный способ их обработки.

Все мои 4 параметра имеют конечную нижнюю и верхнюю границы. Я хотел бы добавить линейное неравенство в качестве жесткого ограничения, например:

def constraint(x):  # needs to be <= 0
    return x[0] - 3.0*x[2]

Но если я попытаюсь использовать Мистик таким образом:

from mystic.solvers import fmin_powell
xopt = fmin_powell(OF, x0=x0, bounds=bounds, constraints=constraint)

Затем Мистик настаивает на вызове целевой функции, чтобы сначала разрешить ограничения, а затем приступить к фактической оптимизации; Так как значение целевой функции не влияет и не влияет на функцию ограничения, как определено выше, я не уверен, почему это происходит. Функция ограничения, определенная выше, просто сообщает Mystic, что область пространства поиска гиперпараметров должна быть недоступна.

Я просмотрел почти все примеры в папке Mystic и наткнулся на альтернативный способ определения жесткого ограничения: используйте функцию штрафа, а затем вызовите магический метод as_constraint, чтобы «преобразовать его» в ограничение. К сожалению, все эти примеры идут примерно так:

from mystic.solvers import fmin_powell
from mystic.constraints import as_constraint
from mystic.penalty import quadratic_inequality

def penalty_function(x): # <= 0.0
    return x[0] - 3.0*x[2]

@quadratic_inequality(penalty_function)
def penalty(x):
    return 0.0

solver = as_constraint(penalty)

result = fmin_powell(OF, x0=x0, bounds=bounds, penalty=penalty)

Есть эта волшебная линия:

solver = as_constraint(penalty)

Я не вижу, что он делает - переменная solver больше никогда не используется.

Итак, на вопрос: есть ли способ определить линейные неравенства в Mystic, которые не требуют дорогостоящего предварительного решения ограничений, а просто говорят Mystic исключить определенные области пространства поиска?

Заранее благодарим вас за любые предложения.

Andrea.

1 Ответ

0 голосов
/ 05 января 2019

Что делает mystic, так это отображает пространство, которое ищет, поэтому вы оптимизируете пространство, преобразованное ядром (для использования жаргона машинного обучения). Вы можете думать об ограничениях как о применении оператора, если знаете, что это означает. Таким образом, y = f(x) при некоторых ограничениях x' = c(x) становится y = f(c(x)). Вот почему оптимизатор оценивает ограничения перед оценкой цели.

Таким образом, вы можете построить ограничение следующим образом:

>>> import mystic.symbolic as ms
>>> equation = 'x1 - 3*a*x2 <= 0'
>>> eqn = ms.simplify(equation, locals=dict(a=1), all=True)
>>> print(eqn)
x1 <= 3*x2
>>> c = ms.generate_constraint(ms.generate_solvers(eqn, nvars=3))
>>> c([1,2,3])
[1, 2, 3]
>>> c([0,100,-100])
[0, -300.0, -100]

Или, если у вас более одного:

>>> equation = '''
... x1 > x2 * x0     
... x0 + x1 < 10
... x1 + x2 > 5
... '''
>>> eqn = ms.simplify(equation, all=True)
>>> print(eqn)
x1 > -x2 + 5
x0 < -x1 + 10
x1 > x0*x2
>>> import mystic.constraints as mc
>>> c = ms.generate_constraint(ms.generate_solvers(eqn), join=mc.and_)
>>> c([1,2,3])
[1, 3.000000000000004, 3]
...