Scipy.optimize.minimize не дает минимальное значение, даже если он видит это значение
Я использую scipy.optimize.minimize, чтобы найти оптимальные параметры для моей целевой функции.
Мой код:
import numpy as np
from scipy.optimize import minimize
from scipy.optimize import Bounds
bounds = Bounds([26,26,8,6,400,100,0,25,2],[36,38,28,28,1800,800,100,50,7])
energy_history = []
x_values = []
def objective(x):
x_trail = x.reshape(1,-1)
x_trail = sc_X.transform(x_trail)
y_trail = regressorSVR.predict(x_trail)
y_trail = y_trail.reshape(1,-1)
y_trail = sc_Y.inverse_transform(y_trail)
return y_trail[0]
def callback(x,y):
fobj = objective(x)
energy_history.append(fobj)
x_values.append(x)
x0 = np.array([26,28,15,7,400,377,40,43,4.3])
res = minimize(objective, x0, method='trust-constr',
options={'verbose': 1}, bounds=bounds,callback=callback)
optimal_values = res.x
energy = res.fun
При заданных начальных значениях полученное мной минимальное значение (res.fun) равно -7.1. Я создаю список (energy_history), чтобы увидеть, как он достигает этого значения. Я вижу некоторые значения, которые меньше -7,1 в этом списке, но тем не менее, почему -7,1 возвращается как минимальное значение.
Есть несколько раз, когда целевая функция достигла значения -21, но почему по-прежнему возвращается -7 как минимум?
0 ответов
Если мы посмотрим на scipy.optimization
документация, которую мы можем видеть, что scipy.optimize.minimize
перечислен под локальной оптимизацией. Основная проблема в том, что ваша проблема невыпуклая и, таким образом, scipy.optimize.minimize
не может гарантировать правильную конвергенцию. Поскольку он также очень недифференцируем, многие алгоритмы не подходят вообще.
scipy.optimize
действительно предоставляет некоторые глобальные алгоритмы оптимизации, хотя их можно найти на странице документации по глобальной оптимизации, а именно: basinhopping
, brute
, а также differential_evolution
, Посмотрите на этот ответ для небольшого объяснения.
В основном вы можете попробовать brute
Во-первых, просто чтобы увидеть какие-либо систематические проблемы. Это в основном решение для перебора и будет медленным, но найдите свой минимум. Более сложный метод будет использовать differential_evolution
, Поскольку ваша функция не совсем гладкая, basinhopping
может не сработать, но все же стоит попробовать и, вероятно, сойдет быстрее всего.