2017-03-20 69 views
2

我有一个优化问题,我需要在python中解决。一般结构多变量Python最小二乘法

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最小化和f, g, h, i and j作为一个列表,其中平方的差为foobar之间的最小返回值。我不知道如何使用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

您当前定义问题的方式等同于最大化bar(假设您将func传递给最小化函数)。由于您不会改变参数aefunc基本上是可以调整的常数和bar的结果之间的差异;由于负号,它将被尝试最大化,因为那样会使整个功能最小化。

我想你实际上想要最小化的是两个函数之间的绝对值或平方差。我说明了用一个简单的例子,我假设函数只返回参数的总和:

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

因此,如预期,对于这个简单的情况下,可以选择参数的方式,这两个函数之间的差别变为0显然,结果你的参数不是唯一的,他们也可以是全部0.

我希望能帮助你的实际功能工作。

编辑:

至于你问least_square,也能正常工作(从上面使用功能的定义);那么总差是确定:

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个参数不会在这个问题而改变,我将它们固定到一定值并不会将它们传递给优化调用。