我应该如何对带有边界的多元且不可微的函数进行优化?

时间:2018-09-13 03:53:01

标签: python python-3.x optimization scipy

我遇到以下优化问题:

目标函数是一个多元且不可微的函数,它以标量列表作为参数并返回标量。从函数内的计算是基于熊猫和一系列滚动,std等操作的意义上来说,这是不可微的。

伪代码如下:

def target_function(x: list) -> float:
    # calculations
    return output

此外,x参数的每个组成部分都有其自己的界限,定义为元组(最小,最大)。那么我应该如何使用scipy.optimize库来查找此函数的全局最小值?还有其他图书馆可以帮助吗?

我已经尝试过scipy.optimize.brute,它使我像永远一样,而scipy.optimize.minimize却从未产生过看似正确的答案。

1 个答案:

答案 0 :(得分:0)

basinhoppingbrutedifferential_evolution是可用于全局优化的方法。您已经发现,蛮力全局优化并不是特别有效。

差分进化是一种随机方法,应该比蛮力更好,但是可能仍需要大量目标函数评估。如果要使用它,则应使用这些参数并查看最适合您的问题的参数。如果您知道目标函数不是“平滑”的,则这种方法往往比其他方法更有效:该函数或其导数可能不连续。

另一方面,跳水池可以进行随机跳跃,但每次跳跃后也可以进行局部放松。如果您的目标函数具有很多局部最小值,这将很有用,但是由于使用了局部松弛,因此函数应该是平滑的。如果您不能轻松地获得函数的梯度,则仍可以尝试使用不需要这些信息的局部最小化器之一进行跳盆。

scipy.optimize.basinhopping例程的优点在于它是非常可定制的。您可以使用take_step定义自定义随机跳转,accept_test覆盖用于决定是否继续或放弃随机跳转和松弛结果的测试,并使用minimizer_kwargs进行调整局部最小化行为。例如,您可以覆盖take_step以使其保持在边界内,然后选择L-BFGS-B最小化器,该最小化器可以在数字上估计函数的梯度并确定参数的边界。如果给它一个渐变,L-BFGS-B会更好地工作,但是我没有使用它,并且它仍然能够很好地将其最小化。请务必阅读本地和全局优化例程中的所有参数,并调整可接受的容差,以提高性能。