Python Scipy.optimize:如何限制参数值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19244527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:14:20  来源:igfitidea点击:

Scipy.optimize: how to restrict argument values

pythonscipy

提问by Alexandra Shchukina

I'm trying to use scipy.optimizefunctions to find a global minimum of a complicated function with several arguments. scipy.optimize.minimizeseems to do the job best of all, namely, the 'Nelder-Mead' method. However, it tends to go to the areas out of arguments' domain (to assign negative values to arguments that can only be positive) and thus returns an error in such cases. Is there a way to restrict the arguments' bounds within the scipy.optimize.minimizefunctionitself? Or maybe within other scipy.optimizefunctions?

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

I've found the following advice:

我找到了以下建议:

When the parameters fall out of the admissible range, return a wildly huge number (far from the data to be fitted). This will (hopefully) penalize this choice of parameters so much that curve_fitwill settle on some other admissible set of parameters as optimal.

当参数超出允许范围时,返回一个非常大的数字(远离要拟合的数据)。这将(希望)严重惩罚这种参数选择,从而curve_fit将其他一些可接受的参数集确定为最佳。

given in this previous answer, but the procedure will take a lot of computational time in my case.

在之前的答案中给出,但在我的情况下,该过程将花费大量计算时间。

采纳答案by ali_m

The Nelder-Mead solver doesn't support constrained optimization, but there are several others that do.

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

TNC and L-BFGS-B both support only bound constraints (e.g. x[0] >= 0), which should be fine for your case. COBYLA and SLSQP are more flexible, supporting any combination of bounds, equality and inequality-based constraints.

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

You can find more detailed info about the solvers by looking at the docs for the standalone functions, e.g. scipy.optimize.fmin_slsqpfor method='SLSQP'.

您可以通过查看独立函数的文档(例如scipy.optimize.fmin_slsqpfor method='SLSQP'.

You can see my previous answer herefor an example of constrained optimization using SLSQP.

您可以在此处查看我之前的回答了解使用 SLSQP 进行约束优化的示例。

回答by unutbu

The minimizefunction has a boundsparameterwhich can be used to restrict the bounds for each variable when using the L-BFGS-B, TNC, COBYLA or SLSQP methods.

minimize函数有一个bounds参数,可用于在使用 L-BFGS-B、TNC、COBYLA 或 SLSQP 方法时限制每个变量的界限。

For example,

例如,

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

回答by Mike McKerns

I know this is late in the game, but maybe have a look at mystic. You can apply arbitrary python functions as penalty functions, or apply bounds constraints, and more… on any optimizer (including the algorithm from scipy.optimize.fmin).

我知道这已经晚了,但也许可以看看mystic. 您可以将任意 Python 函数用作惩罚函数,或者在任何优化器(包括来自 的算法scipy.optimize.fmin)上应用边界约束等等。

https://github.com/uqfoundation/mystic

https://github.com/uqfoundation/mystic

回答by Eric Leschinski

The argument you are looking for is: constraintswhich is one of the arguments passed to scipy.minimize. Roll your own lambda function that receives the parameters to constrain like this:

您要查找的参数是: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)

The above example asserts that all the new candidates in the neighborhood of the last searched item better add up to 50. Change that method to define the permissible search space and the scipy.minimize function will waste no energy considering those answers.

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