使用Scikit Optimize进行黑盒优化



我必须优化一个依赖于外部软件的黑盒问题(没有函数定义也没有导数),这个问题的评估成本非常高。它取决于几个变量,其中一些是实数,另一些是整数。

我认为Scikit Optimize可能是一个不错的选择。

我想知道如果下面的例子(从Scikit优化文档)可以适应我的实际问题。被"f"提供一组给定参数的代价的外部函数。这是一个伪函数,只是为了重现。但是,不要仅仅依赖于"某某",而要让它依赖于"某某"。和";z">

我已经看到了一些Scikit优化面向超参数优化的其他例子(基于Scikit Learn),但它们对我来说似乎不太清楚。

这是最小可复制的例子(崩溃):

import numpy as np
from skopt import gp_minimize
from skopt.space import Integer
from skopt.space import Real

np.random.seed(123)
def f(x,y,z):
return (np.sin(5 * x[0]) * (1 - np.tanh(x[0] ** 2)) *np.random.randn() * 0.1-y[0]**2+z[0]**2)
search_space = list()
search_space.append(Real(-2, 2, name='x'))
search_space.append(Integer(-2, 2, name='y'))
search_space.append(Real(0, 2, name='z'))
res = gp_minimize(f, search_space, n_calls=20)
print("x*=%.2f, y*=%.2f, f(x*,y*)=%.2f" % (res.x[0],res.y[0],res.z[0], res.fun))

致以最诚挚的问候和感谢

您可以使用scikit-optimize中的decorator函数use_named_args来将带有名称的搜索空间传递给成本函数:

import numpy as np
from skopt import gp_minimize
from skopt.space import Integer
from skopt.space import Real
from skopt.utils import use_named_args
np.random.seed(123)
search_space = [
Real(-2, 2, name='x'),
Integer(-2, 2, name='y'),
Real(0, 2, name='z')
]
@use_named_args(search_space)
def f(x, y, z):
return (np.sin(5 * x) * (1 - np.tanh(x ** 2)) *np.random.randn() * 0.1-y**2+z**2)
res = gp_minimize(f, search_space, n_calls=20)

注意,您的OptimizeResultres将优化的参数存储在属性x中,这是一个最佳值数组。这就是为什么你的代码崩溃(即在res中没有yz属性)。您可以获得一个包含映射名称和优化值的字典,如下所示:

optimized_params = {p.name: res.x[i] for i, p in enumerate(search_space)}

最新更新