Scipy.optimize:如何限制参数值

Ale*_*ina 22 python scipy

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

我找到了以下建议:

当参数超出允许范围时,返回一个非常大的数字(远离要安装的数据).这将(希望)对这种参数的选择进行过多的惩罚,以便curve_fit将其他一些允许的参数集合作为最佳参数.

在上一个答案中给出,但在我的情况下,该过程将花费大量的计算时间.

unu*_*tbu 26

minimize函数有一个bounds参数,当使用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.  ]
Run Code Online (Sandbox Code Playgroud)


ali*_*i_m 24

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

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

您可以通过查看文档的独立功能,例如找到求解器的详细信息scipy.optimize.fmin_slsqpmethod='SLSQP'.

您可以在此处查看我之前的答案,以获取使用SLSQP进行约束优化的示例.


Eri*_*ski 7

您要查找的参数是: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)
Run Code Online (Sandbox Code Playgroud)

上面的例子断言最后一个搜索项附近的所有新候选最好加起来为 50。更改该方法以定义允许的搜索空间,scipy.minimize 函数将不会浪费精力考虑这些答案。