2017-03-20 11 views
2

私はPythonで解決する必要がある最適化の問題があります。一般的な構造は、私は正方形の差がfoobar間の最小値であるリストとしてleast_squares最小化を使用しf, g, h, i and jの値を返したいPython Least Squares for multiple variables

def foo(a, b, c, d, e): 
    # do something and return one value 


def bar(a, b, c, d, e, f, g, h, i, j): 
    # do something and return one value 


def func(): 
    return foo(a, b, c, d, e) - bar(a, b, c, d, e, f, g, h, i, j) 

あります。私はこのためにleast_squaresをどう使うべきか分かりません。

私はこれを試してみた:

# Initial values f, g, h, i, j 
x0 =[0.5,0.5,0.5,0.05,0.5] 

# Constraints 
lb = [0,0,0,0,-0.9] 
ub = [1, 100, 1, 0.5, 0.9] 

x = least_squares(func, x0, lb, ub) 

私はxf, g, h, i and j最小値のリストの戻り値であることを取得するにはどうすればよいですか?

+2

'scipy'が提供する' least_squares'メソッドを試しましたか?詳細https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.least_squares.html –

+1

@Anil_Mこの機能をどのように正確に使用しますかは私の質問ですか? – Newtt

答えて

1

現在問題を定義する方法は、funcを最小化関数に渡すと仮定して、barを最大化することと等価です。パラメータaeに変更しないので、funcは、基本的には定数と、調整可能なbarの結果の違いです。負の符号のために、関数全体を最小限に抑えるように最大化しようとします。

実際に最小化したいのは、2つの関数の絶対値または2乗の差です。

from scipy.optimize import minimize 

def foo(a, b, c, d, e): 
    # do something and return one value 

    return a + b + c + d + e 

def bar(a, b, c, d, e, f, g, h, i, j): 
    # do something and return one value 
    return a + b + c + d + e + f + g + h + i + j 

def func1(x): 
    # your definition, the total difference 
    return foo(x[0], x[1], x[2], x[3], x[4]) - bar(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]) 

def func2(x): 
    # quadratic difference 
    return (foo(x[0], x[1], x[2], x[3], x[4]) - bar(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]))**2 

# Initial values for all variables 
x0 = (0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.05, 0.5) 

# Constraints 
# lb = [0,0,0,0,-0.9] 
# ub = [1, 100, 1, 0.5, 0.9] 
# for illustration, a, b, c, d, e are fixed to 0; that should of course be changed 
bnds = ((0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (0., 1), (0., 100.), (0, 1), (0, 0.5), (-0.9, 0.9)) 

res1 = minimize(func1, x0, method='SLSQP', bounds=bnds) 
res2 = minimize(func2, x0, method='SLSQP', bounds=bnds) 

次に、あなたが得る:

print res1.x 
array([ 0. , 0. , 0. , 0. , 0. , 1. , 100. , 1. , 
      0.5, 0.9]) 

print res1.fun 
-103.4 

としては、前述した私は、私は機能だけでパラメータの合計値を返すことを前提とし、簡単な例を使用することを示していますすべてのパラメータは、barを最大にするように上限に移動し、funcを最小にします。適応機能func2については

、あなたが受け取る:

res2.fun 
5.7408853312979541e-19 # which is basically 0 

res2.x 
array([ 0.  , 0.  , 0.  , 0.  , 0.  , 
    0.15254237, 0.15254237, 0.15254237, 0.01525424, -0.47288136]) 

ので、予想通り、この単純なケースのために1は、この2つの機能の違いが明らかに0になるような方法でパラメータを選択することができますあなたのパラメータの結果は一意ではなく、すべて0でもかまいません。

あなたの実際の関数を動作させるのに役立つことを願っています。

EDIT:

あなたは(上から利用機能の定義)も正常に動作しますleast_square、を求めたよう。その後、総違いはokです:

from scipy.optimize import least_squares 

lb = [0,0,0,0,0,0,0,0,0,-0.9] 
ub = [0.1,0.1,0.1,0.1,0.1,1, 100, 1, 0.5, 0.9] 
res_lsq = least_squares(func1, x0, bounds=(lb, ub)) 

は、その後、上記と同じ結果を受け取る:

res_lsq.x 
array([ 1.00000000e-10, 1.00000000e-10, 1.00000000e-10, 
     1.00000000e-10, 1.00000000e-10, 1.52542373e-01, 
     1.52542373e-01, 1.52542373e-01, 1.52542373e-02, 
     -4.72881356e-01]) 

res_lsq.fun 
array([ -6.88463034e-11]) # basically 0 

5つのパラメータがこの問題に変化させることがないように、私は特定の値にそれらを修正しますそれらを最適化呼び出しに渡すことはありません。