2013-10-08 41 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_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。上記の例では、最後の近所ですべての新しい候補者がより良い方法を定義することを50変更まで追加アイテムを検索することを主張する

#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) 

:パラメータは次のように制限するために受け、独自のラムダ関数を転がし許容される検索スペースとscipy.minimize関数は、それらの答えを考慮してエネルギーを無駄にしません。

関連する問題