【问题标题】:Scipy.optimize: how to restrict argument valuesScipy.optimize:如何限制参数值
【发布时间】:2013-10-15 04:31:36
【问题描述】:

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

我找到了以下建议:

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

given in this previous answer,但在我的情况下,该过程将花费大量计算时间。

【问题讨论】:

  • 当输入超出允许范围时,让成本函数返回一个很大的成本是一个非常糟糕的主意,因为搜索函数将花费大部分精力来搜索无限大小的不合格答案空间。使用来自scipy.minimizeconstraint 参数指定一个方法,该方法将告诉算法将其搜索限制在何处。在此处搜索“约束”:docs.scipy.org/doc/scipy/reference/generated/…

标签: python scipy


【解决方案1】:

您要查找的参数是: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 函数将不会浪费精力考虑这些答案。

【讨论】:

    【解决方案2】:

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

    https://github.com/uqfoundation/mystic

    【讨论】:

      【解决方案3】:

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

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

      您可以通过查看独立函数的文档来找到有关求解器的更多详细信息,例如scipy.optimize.fmin_slsqpmethod='SLSQP'

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

      【讨论】:

      • 我刚刚检查了 SciPy 1.7.1,他们通过根据边界裁剪单纯形来允许 Nelder-Mead 算法的边界。
      【解决方案4】:

      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,1) 或 (.1,1),我的结果仍然显示为 0。 1,.5) 绑定。这里有什么补救措施吗?我是用一个列表比较来做这个的,所以 [(.1,.9) for I in range(15)] 作为我的 bnd 并且在某些情况下仍然得到 1 的 1.0 和其他 14 的 0。
      • DUH -- .1 没有进入 1.0 15x -- 哎呀!抱歉,正在使用 5 个安全产品组合并对其进行了扩展,但没想到要更改 min。问题解决了
      猜你喜欢
      • 1970-01-01
      • 2020-08-18
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      相关资源
      最近更新 更多