2013-10-08 40 views
8

我試圖用scipy.optimize函數來查找具有多個參數的複雜函數的全局最小值。 scipy.optimize.minimize似乎最擅長完成這項工作,即'Nelder-Mead'方法。然而,它傾向於從論域的區域(將負值分配給只能爲正的論據),並因此在這種情況下返回錯誤。有沒有辦法限制參數範圍內的scipy.optimize.minimize函數本身?或者也許在其他scipy.optimize功能?Scipy.optimize:如何限制參數值

我已經找到了以下建議:

當參數落在在允許的範圍內,(從數據遠遠要安裝)返回一個瘋狂數量巨大。這將會(希望)懲罰這個參數的選擇,以至於curve_fit將決定一些其他可接受的參數作爲最佳參數。

given in this previous answer,但在我的情況下,該過程將花費大量的計算時間。

+0

當輸入超出允許範圍時,使成本函數返回大量成本是一個非常糟糕的想法,因爲搜索函數將花費其大部分能量搜索無限大的不合格答案空間。使用'scipy.minimize'中的'constraint'參數指定一個方法,告訴算法在哪裏限制搜索。在這裏搜索'約束':http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize –

回答

14

的內爾德 - 米德求解器不支持約束優化,但有幾個人做到這一點。

TNC和L-BFGS-B都只支持約束約束(例如x[0] >= 0),對您的情況應該很好。 COBYLA和SLSQP更加靈活,支持邊界,平等和不平等約束的任意組合。

通過查看獨立功能的文檔,您可以找到有關解算器的更多詳細信息,例如, scipy.optimize.fmin_slsqpmethod='SLSQP'

對於使用SLSQP進行約束優化的示例,您可以看到我以前的回答here

15

minimize函數有一個bounds parameter,它可以用來限制每個變量在使用L-BFGS-B,TNC,COBYLA或SLSQP方法時的界限。

例如,

import scipy.optimize as optimize 

fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2 
res = optimize.minimize(fun, (2, 0), method='TNC', tol=1e-10) 
print(res.x) 
# [ 1.   2.49999999] 

bnds = ((0.25, 0.75), (0, 2.0)) 
res = optimize.minimize(fun, (2, 0), method='TNC', bounds=bnds, tol=1e-10) 
print(res.x) 
# [ 0.75 2. ] 
1

我知道這是比賽後期,但也許看看mystic。你可以應用任意的python函數作爲懲罰函數,或者應用邊界約束,以及更多......在任何優化器上(包括來自scipy.optimize.fmin的算法)。

https://github.com/uqfoundation/mystic

1

你正在尋找的理由是:constraints這是傳遞給的參數之一。滾動接收參數自己的lambda函數來約束這樣的:

#A function to define the space where scipy.minimize should 
#confine its search: 
def apply_sum_constraint(inputs): 
    #return value must come back as 0 to be accepted 
    #if return value is anything other than 0 it's rejected 
    #as not a valid answer. 
    total = 50.0 - np.sum(inputs) 
    return total 

my_constraints = ({'type': 'eq', "fun": apply_sum_constraint }) 
result = spo.minimize(f, 
         guess, 
         method='SLSQP', 
         args=(a, b, c), 
         bounds=((-1.0, 1.0), (-1.0, 1.0)), 
         options={'disp': True}, 
         constraints=my_constraints) 

上面的例子稱,所有在過去的搜索項附近的新的候選人更好地加起來爲50。更改該方法來定義允許的搜索空間和scipy.minimize函數將考慮這些答案浪費能源。