Python 使用scikit学习';高斯过程回归的s白核

Python 使用scikit学习';高斯过程回归的s白核,python,scikit-learn,Python,Scikit Learn,在scikit学习中,有两种方法可以指定高斯过程回归(GPR)的噪声级 第一种方法是在GaussianProcessRegressor类的构造函数中指定参数alpha,该类只是按照预期向对角线添加值 第二种方法是将内核中的噪声级与WhiteKernel合并 GaussianProcessRegressor(参见)的文档称,指定alpha“相当于添加一个c=alpha的白核”。然而,我正在经历一种不同的行为,我想找出原因是什么(当然,什么是“正确的”方式或“真理”) 下面是一个代码片段,它为函数f

在scikit学习中,有两种方法可以指定高斯过程回归(GPR)的噪声级

第一种方法是在GaussianProcessRegressor类的构造函数中指定参数alpha,该类只是按照预期向对角线添加值

第二种方法是将内核中的噪声级与WhiteKernel合并

GaussianProcessRegressor(参见)的文档称,指定alpha“相当于添加一个c=alpha的白核”。然而,我正在经历一种不同的行为,我想找出原因是什么(当然,什么是“正确的”方式或“真理”)

下面是一个代码片段,它为函数f(x)=x^2的扰动版本绘制了两个不同的回归拟合,尽管它们应该显示相同的结果:

import matplotlib.pyplot as plt
import numpy as np
import numpy.random as rnd
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import ConstantKernel as C, RBF, WhiteKernel


rnd.seed(0)

n = 40
xs = np.linspace(-1, 1, num=n)

noise = 0.1
kernel1 = C()*RBF() + WhiteKernel(noise_level=noise)
kernel2 = C()*RBF()

data = xs**2 + rnd.multivariate_normal(mean=np.zeros(n), cov=noise*np.eye(n))

gpr1 = GaussianProcessRegressor(kernel=kernel1, alpha=0.0, optimizer=None)
gpr1.fit(xs[:, np.newaxis], data)

gpr2 = GaussianProcessRegressor(kernel=kernel2, alpha=noise, optimizer=None)
gpr2.fit(xs[:, np.newaxis], data)

xs_plt = np.linspace(-1., 1., num=100)

for gpr in [gpr1, gpr2]:
    pred, pred_std = gpr.predict(xs_plt[:, np.newaxis], return_std=True)

    plt.figure()
    plt.plot(xs_plt, pred, 'C0', lw=2)
    plt.scatter(xs, data, c='C1', s=20)

    plt.fill_between(xs_plt, pred - 1.96*pred_std, pred + 1.96*pred_std,
                     alpha=0.2, color='C0')

    plt.title("Kernel: %s\n Log-Likelihood: %.3f"
              % (gpr.kernel_, gpr.log_marginal_likelihood(gpr.kernel_.theta)),
              fontsize=12)
    plt.ylim(-1.2, 1.2)
    plt.tight_layout()

plt.show()
我已经在查看scikit学习包中的,但无法找出哪里出了问题。或者,我只是在监督一些事情,而结果却很有意义

有没有人知道这里发生了什么,或者有过类似的经历


非常感谢

这里我可能错了,但我相信“指定alpha相当于添加一个c=alpha的白内核”的说法是不正确的

设置GP回归噪声时,噪声仅添加到训练点之间的协方差
K
。添加白噪声内核时,噪声也会添加到测试点之间的协方差
K**


在您的情况下,测试点和训练点是相同的。然而,这三个不同的矩阵可能仍然会被创建。这可能导致此处观察到的差异。

我认为文档不正确。看看这个(我打开的)

在实践中,我所做的是用
白内核
为一个GP装配,然后使用该noice级别。然后,我将该值添加到
alpha
并重新计算必要的变量。一个更简单的选择是使用
alpha
设置和相同的长度刻度制作一个新的GP,但不适合它

我应该注意到,对于这是否是正确的做法,人们并没有普遍接受。我与一位同事进行了讨论,得出了以下结论。这与实验误差产生的噪声数据有关

  • 如果您想对GP进行采样,以预测一个具有更多独立测量的新实验,那么您需要WhiteKernel
  • 如果您想要对可能的潜在真相进行采样,那么您就不需要WhiteKernel,因为您想要的是平滑的响应

也许您可以使用GPflow包,它对潜在函数f和观测y(f+噪声)进行单独预测

  • m.predict\u f
    返回点
    Xnew
    处潜在函数(f)的均值和方差
  • m.predict_y
    返回新数据点的平均值和方差(即包括噪声方差)
太好了,谢谢!我认为这是正确的答案。在我看来,说这种说法“微妙地不正确”是一种轻描淡写的说法。这完全是错误的:)。顺便说一句,我的测试和训练分数是不同的。然而,这并不会改变你答案的正确性。哈哈,你可能是对的。我给自己留了一个便条,以便以后更详细地检查scikit代码,也许可以修改注释。这个问题在PR中进行了讨论、解决和合并。