scipy.minimize, кажется, не придерживается ограничений - PullRequest
0 голосов
/ 01 июня 2018

scipy.minimize не соответствует ограничениям.Вот простой пример, где ограничение предназначено для предотвращения отрицательного аргумента в логарифме, но функция минимизации не придерживается:

import math
from scipy.optimize import minimize

def obj(x,b):
    print "obj x",x
    return math.log(x-b)

def constr(x,b):
    print "constr x",x
    return x-b

x=3.1
b=3
a=minimize(obj,x,args=(b),constraints={'type': 'ineq', 'fun':constr,'args':[b]})

вывод:

constr x [ 3.1]
obj x [ 3.1]
constr x [ 3.1]
obj x [ 3.1]
obj x [ 3.10000001]
constr x [ 3.1]
constr x [ 3.10000001]
obj x [ 3.]
Traceback (most recent call last):
File "scipy_minimize_constraints.py", line 19, in 
a=minimize(obj,x,args=(b),constraints={'type': 'ineq', 'fun':constr,'args':[b]})
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 495, in minimize
constraints, callback=callback, **options)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/slsqp.py", line 378, in _minimize_slsqp
fx = func(x)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 292, in function_wrapper
return function(*(wrapper_args + args))
File "scipy_minimize_constraints.py", line 9, in obj
return math.log(x-b)
ValueError: math domain error

python2.7 Scipy версия 1.0.0

Я что-то не так делаю?

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Ограничение

def constr(x,b):
    return x-b

приводит к x-b >= 0 ( неотрицательно ), но допускает x-b = 0.Тогда log(x-b) не определено, если x-b = 0.Вам нужно будет ввести некоторые эпсилоны вроде:

eps = 1e-12
def constr(x,b):
    return x-b-eps

, которые не приведут к вашей ошибке.

Но может быть более важная проблема: я действительно не думаю решатель (здесь SLSQP) гарантирует, что его итерации будут выполнимыми!Могут быть случаи, когда это будет проблематично.В вашем простом примере вы должны преобразовать ограничение в границы.Это, конечно, менее выразительно (не всегда возможно; но для вашего крошечного примера это так), но эти границы соблюдаются в итерациях!

inferred_lb = b + eps
a = minimize(obj, x, args=(b,), bounds=[(inferred_lb, None)])

(И конечно: не используйте свернуть дляОптимизация размеров. Существует minimal_scalar.)

0 голосов
/ 01 июня 2018

Я не знаю точно, как работает минимизация Сципи, но я думаю, что вы правы, что он не следует ограничениям.

Если в obj (x, b) я попытаюсь напечатать x- б, я получаю отрицательный вывод для последнего цикла, когда он выдает ошибку.

это не совсем удивительно, хотя.минимизируемая функция - это, по сути, log (z) с ограничением z> 0. она не будет сходиться очень медленно ...: p

EDIT: установка параметра ключевого слова "tol" (допустимое отклонение)примерно до 0,1 для минимизатора избавляется от ошибки (как в minimize(..., tol=0.1)).Я до сих пор не знаю, почему это так важно.

РЕДАКТИРОВАТЬ (так как я все еще не могу комментировать): @sascha, это имеет смысл, но почему функция даже оценивает отрицательные значения x- б?Функция минимизации "тестирует" вне своих ограничений только для того, чтобы лучше оптимизировать решение в ней?(Если я задам это как новый вопрос, дайте мне знать.)

...