Scipy.optimize:如何限制参数值

时间:2013-10-08 09:54:21

标签: python scipy

我正在尝试使用scipy.optimize函数来查找具有多个参数的复杂函数的全局最小值。 scipy.optimize.minimize似乎做得最好,即'Nelder-Mead'方法。但是,它倾向于从参数'域中进入区域(将负值分配给只能为正的参数),从而在这种情况下返回错误。有没有办法在scipy.optimize.minimize函数本身内限制参数的界限?或者也许在其他scipy.optimize函数中?

我找到了以下建议:

  

当参数超出允许范围时,返回一个非常大的数字(远离要安装的数据)。这将(希望)惩罚这些参数的选择,以至于curve_fit将在其他一些可接受的参数集上达到最优。

given in this previous answer,但在我的情况下,这个程序需要花费大量的计算时间。

4 个答案:

答案 0 :(得分:21)

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 :(得分:21)

Nelder-Mead求解器不支持约束优化,但还有其他几个算法。

TNC和L-BFGS-B都只支持约束约束(例如x[0] >= 0),这对你的情况应该没问题。 COBYLA和SLSQP更灵活,支持边界,平等和基于不平等的约束的任何组合。

通过查看独立功能的文档,您可以找到有关求解器的更多详细信息,例如: method='SLSQP'的{​​{3}}。

您可以查看我之前的答案scipy.optimize.fmin_slsqp,了解使用SLSQP进行约束优化的示例。

答案 2 :(得分:3)

您要查找的参数是:constraints,这是传递给scipy.minimize的参数之一。滚动你自己的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函数将考虑到这些答案而不会浪费任何能量。 / p>

答案 3 :(得分:1)

我知道这是游戏的后期,但也许看看mystic。您可以将任意python函数作为惩罚函数应用,或者对任何优化器应用边界约束等等(包括来自scipy.optimize.fmin的算法)。

https://github.com/uqfoundation/mystic