0

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

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

我想知道以下示例(来自 Scikit Optimize 文档)是否可以适应我的实际问题。作为“f”一个提供给定参数集成本的外部函数。这是一个虚拟函数,只是为了可重现。但是,不要仅仅依赖于“x”,而是让它依赖于“y”和“z”,它们是其中之一,仅限于整数值。

我已经看到了一些其他面向超参数优化的 Scikit Optimize 示例(基于 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))

最好的问候,谢谢

4

1 回答 1

3

您可以使用use_named_argsscikit-optimize 中的装饰器函数将带有名称的搜索空间传递给成本函数:

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)

请注意,您的OptimizeResult res将优化参数存储在属性中,该属性x是最佳值的数组。这就是您的代码崩溃的原因(即没有属性yzin res)。您可以获得具有映射名称和优化值的字典,如下所示:

optimized_params = {p.name: res.x[i] for i, p in enumerate(search_space)}
于 2021-10-26T11:08:39.563 回答