我想优化一个有几个可变参数作为输入的算法。
对于机器学习任务,Sklearn
提供具有gridsearch
功能的超参数优化。
Python 中是否有一种标准化的方式/库,可以优化不限于机器学习主题的超参数?
我想优化一个有几个可变参数作为输入的算法。
对于机器学习任务,Sklearn
提供具有gridsearch
功能的超参数优化。
Python 中是否有一种标准化的方式/库,可以优化不限于机器学习主题的超参数?
您可以使用 score 方法创建自定义管道/估计器(请参阅链接http://scikit-learn.org/dev/developers/contributing.html#rolling-your-own-estimator)来比较结果。
ParameterGrid也可能对您有所帮助。它将自动填充所有超参数设置。
您可能会考虑 scipy 的optimize.brute,它本质上是相同的,尽管在 API 使用方面不受限制。您只需要定义一个返回标量的函数。
通过蛮力最小化给定范围内的函数。
使用“蛮力”方法,即在多维点网格的每个点处计算函数的值,以找到函数的全局最小值。
来自文档的无耻示例副本:
import numpy as np
from scipy import optimize
params = (2, 3, 7, 8, 9, 10, 44, -1, 2, 26, 1, -2, 0.5)
def f1(z, *params):
x, y = z
a, b, c, d, e, f, g, h, i, j, k, l, scale = params
return (a * x**2 + b * x * y + c * y**2 + d*x + e*y + f)
def f2(z, *params):
x, y = z
a, b, c, d, e, f, g, h, i, j, k, l, scale = params
return (-g*np.exp(-((x-h)**2 + (y-i)**2) / scale))
def f3(z, *params):
x, y = z
a, b, c, d, e, f, g, h, i, j, k, l, scale = params
return (-j*np.exp(-((x-k)**2 + (y-l)**2) / scale))
def f(z, *params):
return f1(z, *params) + f2(z, *params) + f3(z, *params)
rranges = (slice(-4, 4, 0.25), slice(-4, 4, 0.25))
resbrute = optimize.brute(f, rranges, args=params, full_output=True,
finish=optimize.fmin)
print(resbrute[:2]) # x0, feval
(array([-1.05665192, 1.80834843]), -3.4085818767996527)
蛮力函数并不是什么黑魔法,通常人们可能会考虑自己的实现。上面的 scipy-example 有一个更有趣的特性:
完成:可调用,可选
以蛮力最小化的结果作为初始猜测调用的优化函数。finish 应该将 func 和初始猜测作为位置参数,并将 args 作为关键字参数。它还可以将 full_output 和/或 disp 作为关键字参数。如果不使用“抛光”功能,请使用无。有关详细信息,请参阅注释。
我会推荐大多数用例(在连续空间中)。但是一定要对这是做什么有一些最低限度的了解,以了解有些用例您不想这样做(需要离散空间结果;缓慢的函数评估)。
如果您使用的是 sklearn,则您已经安装了 scipy(它是一个依赖项)。
编辑:这里我创建了一些小图(代码)以显示finish
使用一维示例(不是最好的示例,但更容易绘制)正在做什么(本地选择):
你也可以看看贝叶斯优化。在这个github 存储库中,您可以找到简单的实现。
不同之处在于,贝叶斯优化不会查看您输入范围的特定值,而是查找范围内的值。
下面的示例取自他们的存储库,因此您可以看到实现是多么容易!
def black_box_function(x, y):
"""Function with unknown internals we wish to maximize.
This is just serving as an example, for all intents and
purposes think of the internals of this function, i.e.: the process
which generates its output values, as unknown.
"""
return -x ** 2 - (y - 1) ** 2 + 1
from bayes_opt import BayesianOptimization
# Bounded region of parameter space
pbounds = {'x': (2, 4), 'y': (-3, 3)}
optimizer = BayesianOptimization(
f=black_box_function,
pbounds=pbounds,
random_state=1,
)
optimizer.maximize(
init_points=2,
n_iter=3,
)
print(optimizer.max)
>>> {'target': -4.441293113411222, 'params': {'y': -0.005822117636089974, 'x': 2.104665051994087}}
Sklearn 也可以独立于机器学习主题使用,因此,为了完整起见,
我提议:
from sklearn.model_selection import ParameterGrid
param_grid = {'value_1': [1, 2, 3], 'value_2': [0, 1, 2, 3, 5]}
for params in ParameterGrid(param_grid):
function(params['value_1'], params['value_2'])
在此处查找详细文档。