我正在尋找一個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