我正在寻找一个scipy/numpy内的优化程序,它可以解决非线性最小二乘类型问题(例如,将参数函数拟合到大型数据集),但包括边界和约束条件(例如,要优化的参数的最小值和最大值)。目前我使用的是mpfit的python版本(翻译自idl ...):这显然不是最佳的,虽然它工作得很好。scipy.optimize.leastsq有约束约束
python/scipy/etc中的一个高效的例程可能非常棒! 任何输入是非常欢迎这里:-)
谢谢!
我正在寻找一个scipy/numpy内的优化程序,它可以解决非线性最小二乘类型问题(例如,将参数函数拟合到大型数据集),但包括边界和约束条件(例如,要优化的参数的最小值和最大值)。目前我使用的是mpfit的python版本(翻译自idl ...):这显然不是最佳的,虽然它工作得很好。scipy.optimize.leastsq有约束约束
python/scipy/etc中的一个高效的例程可能非常棒! 任何输入是非常欢迎这里:-)
谢谢!
scipy在scipy.optimize中有几个constrained optimization routines。受限最小二乘变体是scipy.optimize.fmin_slsqp
scipy.optimize.least_squares in scipy 0.17(2016年1月) 句柄bounds;使用,而不是这个黑客。
束缚约束可以容易地进行二次, 并通过leastsq与其余部分一起最小化。假设你想最小化10个方块的总和,所以你的func(p)是一个10-矢量[f0(p)... f9(p)],
想要0 < = p_i < = 1的3个参数。
考虑“桶功能”最大( - p,0,p - 1), 这是0内部0和外部正面,像一个\ _____ /浴缸。
如果我们给leastsq
13长的矢量
[ f0(p), f1(p), ... f9(p), w*tub(p0), w*tub(p1), w*tub(p2) ]
与W =说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 n x 2 list or array `[[lo_0,hi_0], [lo_1, hi_1] ...]`.
Use e.g. [0, inf]; do not use NaNs.
A bound e.g. [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 e.g. 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
我已经收到这个错误,当我试图实现它(Python 2.7):'文件“[/ PHPF]”,至少49行, ) 文件“[...]/minpack.py”,第369行,最小格数 shape,dtype = _check_func('leastsq','func',func,x0,args,n) File“[... ])/minpack.py“,第20行,在_check_func中 res = atleast_1d(thefunc(*((x0 [:numinputs]),+ args))) TypeError:
@f_ficarola,对不起,args =是越野车;请剪切/粘贴并再次尝试 – denis 2015-01-08 16:03:46
感谢您的快速回复,denis。然而,在此期间,我发现了这个:'scipy.optimize.minimize(residualsModel,x0,args =(arg1,arg2,...),method ='SLSQP',bounds = [(xmin,xmax)] )'。你的代码有什么不同吗? – 2015-01-08 18:40:28
看一看: http://lmfit.github.io/lmfit-py/,它应该解决您的问题。
感谢您的提示:一个问题是,我希望能够有一个自洽的Python模块,包括有界非线性最小平方部分。这意味着要么用户将不得不安装lmfit,要么我将整个软件包包含在我的模块中。我将首先尝试fmin_slsqp,因为这是一个已经集成在scipy中的函数。但lmfit似乎正是我所需要的! – user1293231 2012-04-01 11:28:57
考虑到您已经依赖SciPy,它不在标准库中。 lmfit在pypi上,对大多数用户来说应该很容易安装。 – chthonicdaemon 2015-01-10 15:56:06
链接已损坏! – denfromufa 2016-10-18 22:21:39
长久以来,Scipy一直缺乏以最佳方式解决非线性最小二乘问题的能力,如mpfit所做的那样。
这个功能强大的功能终于在Scipy 0.17中引入,并且新功能scipy.optimize.least_squares。
这个新函数可以使用合适的信赖域算法来处理约束约束,并优化使用非线性函数的平方和性质。
注:
通过@denis提出的解决方案具有引入不连续的“浴盆功能”的重大问题。这会导致为平滑函数设计的scipy.optimize.leastsq
优化,效率非常低,并且可能不稳定,当边界交叉时。
采用scipy.optimize.minimize
与method='SLSQP'
(如@f_ficarola建议的)或scipy.optimize.fmin_slsqp
(如@马特建议的),必须被最小化不利用的功能的平方和的-性质的主要问题。这些函数都是为了尽量减少标量函数而设计的(尽管误导性名称也适用于fmin_slsqp)。这些方法效率较低,并且不如适当的方法准确。
谢谢!将在未来几天测试这个对mpfit我的问题,并会尽快报告! – user1293231 2012-03-26 22:19:31
刚刚试过slsqp。我可能没有正确使用它,但基本上它没有太大的好处。当使用太低的epsilon值时,似乎会崩溃。否则,不会改变我的输入参数中的任何内容(或差不多)。我会做一些调试,但看起来并不那么容易使用(到目前为止)。将进一步尝试。 – user1293231 2012-04-03 12:41:11
事实上,我只是得到以下错误==> linesearch的正方向派生(退出模式8)。这就是为什么我没有得到任何地方....不是很有用。任何提示? – user1293231 2012-04-03 13:14:46