我正在尝试使用scipy.optimize
函数来查找具有多个参数的复杂函数的全局最小值。 scipy.optimize.minimize
似乎做得最好,即'Nelder-Mead'方法。但是,它倾向于从参数'域中进入区域(将负值分配给只能为正的参数),从而在这种情况下返回错误。有没有办法在scipy.optimize.minimize
函数本身内限制参数的界限?或者也许在其他scipy.optimize
函数中?
我找到了以下建议:
当参数超出允许范围时,返回一个非常大的数字(远离要安装的数据)。这将(希望)惩罚这些参数的选择,以至于
curve_fit
将在其他一些可接受的参数集上达到最优。
given in this previous answer,但在我的情况下,这个程序需要花费大量的计算时间。
答案 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
的算法)。