Учебники

SciPy — Оптимизация

Пакет scipy.optimize предоставляет несколько часто используемых алгоритмов оптимизации. Этот модуль содержит следующие аспекты —

  • Неограниченная и ограниченная минимизация многомерных скалярных функций (минимизация ()) с использованием различных алгоритмов (например, BFGS, симплекс Нелдера-Мида, градиент сопряженного Ньютона, COBYLA или SLSQP)

  • Процедуры глобальной (грубой силы) оптимизации (например, отжиг (), тазобедренный отбор ())

  • Алгоритмы минимизации наименьших квадратов (leastsq ()) и аппроксимации кривой (curve_fit ())

  • Скалярные одномерные функции минимизаторы (minim_scalar ()) и корневые искатели (newton ())

  • Решатели системы многомерных уравнений (root ()) с использованием различных алгоритмов (например, гибридный метод Пауэлла, Левенберга-Марквардта или крупномасштабные методы, такие как Ньютон-Крылов)

Неограниченная и ограниченная минимизация многомерных скалярных функций (минимизация ()) с использованием различных алгоритмов (например, BFGS, симплекс Нелдера-Мида, градиент сопряженного Ньютона, COBYLA или SLSQP)

Процедуры глобальной (грубой силы) оптимизации (например, отжиг (), тазобедренный отбор ())

Алгоритмы минимизации наименьших квадратов (leastsq ()) и аппроксимации кривой (curve_fit ())

Скалярные одномерные функции минимизаторы (minim_scalar ()) и корневые искатели (newton ())

Решатели системы многомерных уравнений (root ()) с использованием различных алгоритмов (например, гибридный метод Пауэлла, Левенберга-Марквардта или крупномасштабные методы, такие как Ньютон-Крылов)

Неограниченная и ограниченная минимизация многомерных скалярных функций

Функция minimal () обеспечивает общий интерфейс с неограниченными и ограниченными алгоритмами минимизации для многомерных скалярных функций в scipy.optimize . Чтобы продемонстрировать функцию минимизации, рассмотрим задачу минимизации функции Розенброка NN-переменных:

f(x)= sumN1i=1100(xix2i1)

Минимальное значение этой функции равно 0, что достигается при xi = 1.

Симплексный алгоритм Нелдера – Мида

В следующем примере процедура minimal () используется с симплексным алгоритмом Nelder-Mead (method = ‘Nelder-Mead’) (выбирается через параметр метода). Давайте рассмотрим следующий пример.

import numpy as np
from scipy.optimize import minimize

def rosen(x):

x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(rosen, x0, method='nelder-mead')

print(res.x)

Вышеуказанная программа сгенерирует следующий вывод.

[7.93700741e+54  -5.41692163e+53  6.28769150e+53  1.38050484e+55  -4.14751333e+54]

Симплексный алгоритм — это, вероятно, самый простой способ минимизировать довольно корректную функцию. Он требует только оценки функций и является хорошим выбором для простых задач минимизации. Однако, поскольку он не использует какие-либо оценки градиента, может потребоваться больше времени, чтобы найти минимум.

Другим алгоритмом оптимизации, который требует только вызовов функций, чтобы найти минимум, является метод Пауэлла , который доступен путем установки method = ‘powell’ в функции minimal ().

Наименьших квадратов

Решить нелинейную задачу наименьших квадратов с оценками переменных. Учитывая невязки f (x) (m-мерная вещественная функция от n вещественных переменных) и функцию потерь rho (s) (скалярная функция), наименьшие квадраты находят локальный минимум функции стоимости F (x). Давайте рассмотрим следующий пример.

В этом примере мы находим минимум функции Розенброка без границ для независимых переменных.

#Rosenbrock Function
def fun_rosenbrock(x):
   return np.array([10 * (x[1] - x[0]**2), (1 - x[0])])
   
from scipy.optimize import least_squares
input = np.array([2, 2])
res = least_squares(fun_rosenbrock, input)

print res

Обратите внимание, что мы предоставляем только вектор невязок. Алгоритм строит функцию стоимости как сумму квадратов невязок, которая дает функцию Розенброка. Точный минимум находится при х = [1,0,1,0].

Вышеуказанная программа сгенерирует следующий вывод.

active_mask: array([ 0., 0.])
      cost: 9.8669242910846867e-30
      fun: array([ 4.44089210e-15, 1.11022302e-16])
      grad: array([ -8.89288649e-14, 4.44089210e-14])
      jac: array([[-20.00000015,10.],[ -1.,0.]])
   message: '`gtol` termination condition is satisfied.'
      nfev: 3
      njev: 3
   optimality: 8.8928864934219529e-14
      status: 1
      success: True
         x: array([ 1., 1.])

Поиск корней

Давайте разберемся, как поиск корней помогает в SciPy.

Скалярные функции

Если у одного есть уравнение с одной переменной, есть четыре различных алгоритма поиска корней, которые можно попробовать. Каждый из этих алгоритмов требует конечных точек интервала, в котором ожидается корень (потому что функция меняет знаки). В общем, brentq — лучший выбор, но другие методы могут быть полезны в определенных обстоятельствах или для академических целей.

Решение с фиксированной точкой

Проблема, тесно связанная с нахождением нулей функции, — это проблема нахождения неподвижной точки функции. Фиксированная точка функции — это точка, в которой оценка функции возвращает точку: g (x) = x. Ясно, что неподвижная точка gg является корнем f (x) = g (x) −x. Эквивалентно, корень ff — это точка с фиксированной точкой g (x) = f (x) + x. Процедура fixed_point предоставляет простой итеративный метод, использующий ускорение последовательности Айткенса для оценки фиксированной точки gg , если задана начальная точка.

Наборы уравнений

Найти корень системы нелинейных уравнений можно с помощью функции root () . Доступно несколько методов, среди которых hybr (по умолчанию) и lm, соответственно, используют гибридный метод Пауэлла и метод Левенберга-Марквардта из MINPACK.

В следующем примере рассматривается трансцендентное уравнение с одной переменной.

x 2 + 2cos (x) = 0

Корень которого можно найти следующим образом —

import numpy as np
from scipy.optimize import root
def func(x):
   return x*2 + 2 * np.cos(x)
sol = root(func, 0.3)
print sol

Вышеуказанная программа сгенерирует следующий вывод.