【问题标题】:Using scikit-learn's WhiteKernel for Gaussian Process Regression使用 scikit-learn 的 WhiteKernel 进行高斯过程回归
【发布时间】:2019-07-26 01:05:31
【问题描述】:

在 scikit-learn 中有两种方法可以指定高斯过程回归 (GPR) 的噪声级别。

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

第二种方法是将内核中的噪声级别与WhiteKernel结合起来。

GaussianProcessRegressor 的文档(请参阅 documentation here)说,指定 alpha 是“相当于添加带有 c=alpha 的 WhiteKernel” .然而,我正在经历一种不同的行为,并想找出原因是什么(当然,“正确”的方式或“真相”是什么)。

这是一个代码 sn-p 为函数 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-learn 包中的 implementation,但无法找出问题所在。或者,也许我只是在监督某些事情,并且输出非常有意义。

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

非常感谢!

【问题讨论】:

  • 该问题已在 PR #15990 中讨论、解决和合并。

标签: python scikit-learn


【解决方案1】:

我在这里可能是错的,但我认为“指定 alpha 是“等同于添加具有 c=alpha 的 WhiteKernel”的说法是不正确的。

设置 GP-Regression 噪声时,噪声仅添加到训练点之间的协方差K。添加 Whitenoise-Kernel 时,噪声也会添加到测试点之间的协方差K**

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

【讨论】:

  • 太好了,谢谢!我认为这是正确的答案。在我看来,说这种说法“有点不正确”是轻描淡写的。这是完全错误的:)。顺便说一句,我的测试和训练点不同。但是,这不会改变您答案的正确性。
  • 哈哈,你可能是对的。我给自己做了一个记录,以便稍后更详细地检查 scikit 代码,并可能修复评论。
【解决方案2】:

我认为文档不正确。请参阅github issue #13267 关于这个(我打开的)。

在实践中,我所做的是将WhiteKernel 安装在GP 上,然后达到该级别。然后我将该值添加到alpha 并重新计算必要的变量。一个更简单的替代方法是使用 alpha 集和相同的长度比例制作一个新的 GP,但不适合它。

我应该指出,这是否是正确方法并没有被普遍接受。我与一位同事进行了讨论,我们得出了以下结论。这与来自实验误差的数据噪声有关

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

【讨论】:

    【解决方案3】:

    https://gpflow.readthedocs.io/en/awav-documentation/notebooks/regression.html

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

    • m.predict_f 返回潜函数 (f) 在点 Xnew 处的均值和方差。
    • m.predict_y 返回新数据点的均值和方差(即包括噪声方差)。

    【讨论】:

      猜你喜欢
      • 2018-10-15
      • 2019-09-15
      • 2013-12-26
      • 2015-06-18
      • 2020-03-11
      • 2017-05-25
      • 2020-10-16
      • 2020-05-30
      相关资源
      最近更新 更多