使用内部支持的优化器在 scikit-learn 中针对 GPR 优化 RBF 内核的内核参数

Optimize the Kernel parameters of RBF kernel for GPR in scikit-learn using internally supported optimizers

平方指数或RBF核的基本方程如下:

这里l是长度尺度,sigma是方差参数。长度比例控制两个点看起来如何相似,因为它只是放大 x 和 x' 之间的距离。方差参数控制函数的平滑程度。

我想 optimize/train 这些参数(l 和 sigma)与我的训练数据集。我的训练数据集形式如下:

X: 二维笛卡尔坐标作为输入数据

y: Wi-Fi 设备在二维坐标点的无线电信号强度 (RSS) 作为观测输出

根据sklearn,GaussianProcessRegressor class 定义为:

class sklearn.gaussian_process.GaussianProcessRegressor(kernel=None, alpha=1e-10, optimizer=’fmin_l_bfgs_b’, n_restarts_optimizer=0, normalize_y=False, copy_X_train=True, random_state=None)

这里,optimizer 是一个字符串或可调用的 L-BFGS-B 算法作为默认优化算法 (“fmin_l_bfgs_b”)。 optimizer 可以是内部支持的用于优化内核参数的优化器之一,由字符串指定,也可以是作为可调用对象传递的外部定义的优化器。此外,scikit-learn 中唯一可用的内部优化器是 fmin_l_bfgs_b。但是,我了解到 scipy package has many more optimizers. Since I wanted to use trust-region-reflective algorithm 来优化超参数,我尝试按如下方式实现算法:

def fun_rosenbrock(Xvariable):
    return np.array([10*(Xvariable[1]-Xvariable[0]**2),(1-Xvariable[0])])
Xvariable = [1.0,1.0]
kernel = C(1.0, (1e-5, 1e5)) * RBF(1, (1e-1, 1e3))
trust_region_method = least_squares(fun_rosenbrock,[10,20,30,40,50],bounds=[0,100], method ='trf')

gp = GaussianProcessRegressor(kernel=kernel, optimizer = trust_region_method, alpha =1.2, n_restarts_optimizer=10)
gp.fit(X, y)

因为我无法弄清楚参数 'fun' 在我的例子中到底是什么,所以我求助于使用 this 示例中的 rosenbrock 函数(该示例位于页面底部)。我在控制台中收到以下错误。

我使用scipy包优化内核参数的方法是否正确?如何打印参数的优化值?在我的例子中,scipy.optimize.least_squares 中的参数 'fun' 是什么?

谢谢!

这里主要存在三个问题:

  1. 正在优化的objective函数是rosenbrock函数,它是一个用于优化目的的测试函数。它需要是一个成本函数,根据内核参数进行优化,在 GaussianProcessRegressor 内部,这是对数边际似然,可以作为参数传递给优化器。
  2. 内部需要最大化对数边际似然优化器。请参阅第 1.7.1 节 here. Scipy 最小二乘法最小化 objective 函数,因此您可能需要最小化 objective 函数的反函数。
  3. 传递给GaussianProcessRegressor的优化器的格式,需要以'optimizer'参数下指定的格式传递in the docs.

作为部分工作示例,忽略内核定义以强调优化器:

import numpy as np
from scipy.optimize import minimize,least_squares
from sklearn.gaussian_process import GaussianProcessRegressor

def trust_region_optimizer(obj_func, initial_theta, bounds):
    trust_region_method = least_squares(1/obj_func,initial_theta,bounds,method='trf')
    return (trust_region_method.x,trust_region_method.fun)

X=np.random.random((10,4))
y=np.random.random((10,1))
gp = GaussianProcessRegressor(optimizer = trust_region_optimizer, alpha =1.2, n_restarts_optimizer=10)
gp.fit(X, y)

scipy优化器return一个结果对象,以rosenbrock测试函数的最小化为例:

from scipy.optimize import least_squares,rosen
res=least_squares(rosen,np.array([0,0]),method='trf')

如上所示,可以使用以下方式访问优化值:

res.x

以及要最小化的函数的结果值:

res.fun

这就是 'fun' 参数所代表的内容。然而,既然优化器在内部工作,您将需要从 scikit-learn 访问结果函数值:

gp.log_marginal_likelihood_value_