scipy.optimize.leastsq со связанными ограничениями

Я ищу оптимизационную процедуру в scipy / numpy, которая могла бы решить проблему нелинейного типа наименьших квадратов (например, подгонку параметрической функции к большому набору данных), но включая оценки и ограничения (например, минимумы и максимумы для параметров, которые должны быть оптимизировано). На данный момент я использую python-версию mpfit (переведена из idl …): это явно не оптимально, хотя работает очень хорошо.

Эффективная процедура в python / scipy / etc может быть отличной! Любой вход очень приветствуется здесь 🙂

благодаря!

4 Solutions collect form web for “scipy.optimize.leastsq со связанными ограничениями”

scipy.optimize.least_squares в scipy 0.17 (январь 2016) обрабатывает границы; используйте это, а не этот хак.


Связанные ограничения можно легко сделать квадратичными и свести к минимуму с помощью наименьших квадратов вместе с остальными.
Скажем, вы хотите свести к минимуму сумму из 10 квадратов Σ f_i (p) ^ 2, поэтому ваш func (p) является 10-вектором [f0 (p) … f9 (p)],
а также хотите, чтобы 0 <= p_i <= 1 для 3 параметров.
Рассмотрим «функцию ванны» max (- p, 0, p – 1), которая равна 0 внутри 0 .. 1 и положительна вне, как a \ _____ / tub.
Если мы дадим leastsq 13-длинного вектора

 [ f0(p), f1(p), ... f9(p), w*tub(p0), w*tub(p1), w*tub(p2) ] 

с w = say 100, это минимизирует сумму квадратов партии: ванны будут ограничивать 0 <= p <= 1. Общее lo <= p <= hi похоже.
Следующий код – это всего лишь оболочка, которая работает с leastsq например, с таким 13-длинным вектором для минимизации.

 # leastsq_bounds.py # see also test_leastsq_bounds.py on gist.github.com/denis-bz from __future__ import division import numpy as np from scipy.optimize import leastsq __version__ = "2015-01-10 jan denis" # orig 2012 #............................................................................... def leastsq_bounds( func, x0, bounds, boundsweight=10, **kwargs ): """ leastsq with bound conatraints lo <= p <= hi run leastsq with additional constraints to minimize the sum of squares of [func(p) ...] + boundsweight * [max( lo_i - p_i, 0, p_i - hi_i ) ...] Parameters ---------- func() : a list of function of parameters `p`, [err0 err1 ...] bounds : an nx 2 list or array `[[lo_0,hi_0], [lo_1, hi_1] ...]`. Use eg [0, inf]; do not use NaNs. A bound eg [2,2] pins that x_j == 2. boundsweight : weights the bounds constraints kwargs : keyword args passed on to leastsq Returns ------- exactly as for leastsq, http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html Notes ----- The bounds may not be met if boundsweight is too small; check that with eg check_bounds( p, bounds ) below. To access `x` in `func(p)`, `def func( p, x=xouter )` or make it global, or `self.x` in a class. There are quite a few methods for box constraints; you'll maybe sing a longer song ... Comments are welcome, test cases most welcome. """ # Example: test_leastsq_bounds.py if bounds is not None and boundsweight > 0: check_bounds( x0, bounds ) if "args" in kwargs: # 8jan 2015 args = kwargs["args"] del kwargs["args"] else: args = () #............................................................................... funcbox = lambda p: \ np.hstack(( func( p, *args ), _inbox( p, bounds, boundsweight ))) else: funcbox = func return leastsq( funcbox, x0, **kwargs ) def _inbox( X, box, weight=1 ): """ -> [tub( Xj, loj, hij ) ... ] all 0 <=> X in box, lo <= X <= hi """ assert len(X) == len(box), \ "len X %d != len box %d" % (len(X), len(box)) return weight * np.array([ np.fmax( lo - x, 0 ) + np.fmax( 0, x - hi ) for x, (lo,hi) in zip( X, box )]) # def tub( x, lo, hi ): # """ \___/ down to lo, 0 lo .. hi, up from hi """ # return np.fmax( lo - x, 0 ) + np.fmax( 0, x - hi ) #............................................................................... def check_bounds( X, box ): """ print Xj not in box, loj <= Xj <= hij return nr not in """ nX, nbox = len(X), len(box) assert nX == nbox, \ "len X %d != len box %d" % (nX, nbox) nnotin = 0 for j, x, (lo,hi) in zip( range(nX), X, box ): if not (lo <= x <= hi): print "check_bounds: x[%d] %g is not in box %g .. %g" % (j, x, lo, hi) nnotin += 1 return nnotin 

scipy имеет несколько ограниченных процедур оптимизации в scipy.optimize. Ограниченный вариант наименьших квадратов – scipy.optimize.fmin_slsqp

Возможность решения нелинейной задачи наименьших квадратов с оценками оптимальным образом, как mpfit, уже давно отсутствует у Scipy.

Эта запрошенная функциональность была наконец введена в Scipy 0.17, с новой функцией scipy.optimize.least_squares .

Эта новая функция может использовать правильный алгоритм области доверия для работы с связанными ограничениями и оптимально использовать размер квадратов для нелинейной функции для оптимизации.

Заметки:

Решение, предложенное @denis, имеет основную проблему введения разрывной «функции ванны». Это scipy.optimize.leastsq оптимизацию scipy.optimize.leastsq , предназначенную для гладких функций, очень неэффективную и, возможно, неустойчивую, когда граница пересекается.

Использование scipy.optimize.minimize с помощью method='SLSQP' (как предложено @f_ficarola) или scipy.optimize.fmin_slsqp (как предложено scipy.optimize.fmin_slsqp ), имеет основную проблему не использования суммы квадратного характера функция, которая должна быть минимизирована. Эти функции предназначены для минимизации скалярных функций (правда также для fmin_slsqp, несмотря на вводящее в заблуждение имя). Эти подходы менее эффективны и менее точны, чем правильные.

Посмотрите: http://newville.github.com/lmfit-py/ , он должен решить вашу проблему.

  • Какой из них относится к разрезанию столбцов и сортировке строк?
  • Интегрирование многомерного интеграла в scipy
  • Как удалить расширение на blob, вызванное морфологией
  • Разделите оси в matplotlib только для части подзаголовков
  • Каков самый быстрый способ минимизации функции в python?
  • Как нарисовать линию внутри участка рассеяния
  • Оценка малого временного сдвига между двумя временными рядами
  • Как я могу использовать scipy.ndimage.interpolation.affine_transform для поворота изображения вокруг своего центра?
  • Как читать систему дифференциальных уравнений из текстового файла для решения системы с помощью scipy.odeint?
  • Почему numpy.array () иногда очень медленный?
  • Изменение структуры массива numpy, обеспечивающего заданное значение
  • Python - лучший язык программирования в мире.