Я использую scikit-learn для подгонки модели процесса Гаусса к косинусоидальной волне с шумом:
import numpy as np
import matplotlib.pyplot as plt
import sklearn.gaussian_process.kernels as kern
from sklearn.gaussian_process import GaussianProcessRegressor
## Generate data
xs_ = np.linspace(-4*np.pi, 4*np.pi, 100) # 2 periods for cos wave
y = np.cos(xs_) + np.random.normal(0, 0.5, 100)
## Define Gaussian process
l = 4*np.pi ## length scale; intentionally large
alpha = 1 ## noise on diagonal
kernel = kern.RBF(length_scale=l)
gp_prior = GaussianProcessRegressor(kernel=kernel, alpha=alpha, random_state=12)
## Fit and predict on new data
gp_pos = gp_prior.fit(xs_[:,np.newaxis], y)
xss_ = np.linspace(-4*np.pi, 4*np.pi, 200) ## new data
y_mean = gp_pos.predict(xss_[:,np.newaxis])
Результат этого прогона по сути является плоской линией, потому что оптимизатор fmin_l_bfgs_b
не сделал найти достаточный минимум (можно подтвердить печатью gp_pos.kernel_
).
Чтобы увидеть, как другой выбор оптимизатора может дать лучшие результаты, я включил оптимизатор scipy.optimize differential_evolution
в функцию, предложенную в документации scikit-learn :
import scipy.optimize as opt
def optimizer(obj_func, initial_theta, bounds):
res = opt.differential_evolution(func=obj_func, bounds=bounds, args=(initial_theta,))
theta_opt = res.x
func_min = res.fun
return theta_opt, func_min
Работает, когда l=1
только . Когда l = 4*np.pi
:
l = 4*np.pi
alpha = 1
kernel = kern.RBF(length_scale=l) # specify the kernel
gp_prior = GaussianProcessRegressor(kernel=kernel, alpha=alpha, optimizer=optimizer, random_state=12)
## Fit :
gp_pos = gp_prior.fit(xs_[:,np.newaxis], y)
я получаю следующую ошибку:
RuntimeError: The map-like callable must be of the form f(func, iterable), returning a sequence of numbers the same length as 'iterable'
Есть идеи, чего мне не хватает? Мне бы очень хотелось, чтобы этот вид оптимизации гиперпараметров происходил в действии!
Заранее спасибо!