How should I scipy.optimize a multivariate and non-differentiable function with boundaries?

Nat*_*han 5 python optimization scipy python-3.x

I come upon the following optimization problem:

The target function is a multivariate and non-differentiable function which takes as argument a list of scalars and return a scalar. It is non-differentiable in the sense that the computation within the function is based on pandas and a series of rolling, std, etc. actions.

The pseudo code is below:

def target_function(x: list) -> float:
    # calculations
    return output
Run Code Online (Sandbox Code Playgroud)

Besides, each component of the x argument has its own bounds defined as a tuple (min, max). So how should I use the scipy.optimize library to find the global minimum of this function? Any other libraries could help?

I already tried scipy.optimize.brute, which took me like forever and scipy.optimize.minimize, which never produced a seemingly correct answer.

小智 3

basinhoppingbrute、 和differential_evolution是可用于全局优化的方法。正如您已经发现的,强力全局优化不会特别有效。

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

另一方面,盆地跳跃会进行随机跳跃,但也会在每次跳跃后使用局部松弛。如果您的目标函数有许多局部极小值,但由于使用了局部松弛,该函数应该是平滑的,这非常有用。如果您无法轻松获得函数的梯度,您仍然可以尝试使用不需要此信息的局部最小化器之一进行盆地跳跃。

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