python - scikit-learn 中的多输出高斯过程回归
问题描述
我正在使用scikit learn进行高斯过程回归 (GPR) 操作来预测数据。我的训练数据如下:
x_train = np.array([[0,0],[2,2],[3,3]]) #2-D cartesian coordinate points
y_train = np.array([[200,250, 155],[321,345,210],[417,445,851]]) #observed output from three different datasources at respective input data points (x_train)
需要预测均值和方差/标准差的测试点 (2-D) 是:
xvalues = np.array([0,1,2,3])
yvalues = np.array([0,1,2,3])
x,y = np.meshgrid(xvalues,yvalues) #Total 16 locations (2-D)
positions = np.vstack([x.ravel(), y.ravel()])
x_test = (np.array(positions)).T
现在,在运行 GPR ( GausianProcessRegressor
) 拟合后(这里,ConstantKernel 和 RBF 的乘积用作 中的 Kernel GaussianProcessRegressor
),可以通过以下代码行预测均值和方差/标准差:
y_pred_test, sigma = gp.predict(x_test, return_std =True)
在打印预测均值 ( y_pred_test
) 和方差 ( sigma
) 时,我会在控制台中打印以下输出:
在预测值(平均值)中,打印内部数组内具有三个对象的“嵌套数组”。可以假设内部数组是每个数据源在每个二维测试点位置的预测平均值。但是,打印的方差仅包含一个包含 16 个对象的数组(可能是 16 个测试位置点)。我知道方差提供了估计不确定性的指示。因此,我期待每个测试点的每个数据源的预测方差。我的期望错了吗?如何在每个测试点获得每个数据源的预测方差?是不是因为代码错误?
解决方案
好吧,你确实无意中撞到了一座冰山……
作为前奏,让我们明确一点,方差和标准差的概念仅适用于标量变量;对于向量变量(如您自己的 3d 输出),方差的概念不再有意义,而是使用协方差矩阵(维基百科,Wolfram)。
继续前奏,根据方法上的 scikit-learn 文档,您的形状确实符合sigma
预期(即您的情况没有编码错误):predict
返回:
y_mean : 数组,形状 = (n_samples, [n_output_dims])
查询点的预测分布均值
y_std : 数组,形状 = (n_samples,),可选
查询点预测分布的标准差。仅在 return_std 为 True 时返回。
y_cov:数组,形状=(n_samples,n_samples),可选
联合预测分布的协方差查询点。仅当 return_cov 为 True 时返回。
结合我之前关于协方差矩阵的评论,第一选择是尝试predict
带参数的函数return_cov=True
(因为询问向量变量的方差是没有意义的);但同样,这将导致 16x16 矩阵,而不是 3x3 矩阵(3 个输出变量的协方差矩阵的预期形状)......
弄清了这些细节之后,让我们进入问题的本质。
您的问题的核心是在实践和相关教程中很少提及(甚至暗示)的东西:具有多个输出的高斯过程回归非常重要,仍然是一个活跃的研究领域。可以说,scikit-learn 不能真正处理这种情况,尽管它表面上看起来会这样做,但至少不会发出一些相关的警告。
让我们在最近的科学文献中寻找对这一说法的一些佐证:
具有多个响应变量的高斯过程回归(2015) - 引用(强调我的):
大多数 GPR 实现仅对单个响应变量进行建模,因为难以为相关的多个响应变量制定协方差函数,它不仅描述了数据点之间的相关性,还描述了响应之间的相关性。在本文中,我们提出了多响应 GPR 的协方差函数的直接公式,基于 [...]
尽管 GPR 被广泛用于各种建模任务,但 GPR 方法仍然存在一些突出的问题。本文特别感兴趣的是需要对多个响应变量进行建模。传统上,一个响应变量被视为一个高斯过程,多个响应独立建模而不考虑它们的相关性。这种务实而直接的方法在许多应用中被采用(例如 [7, 26, 27]),尽管它并不理想。对多响应高斯过程建模的一个关键是协方差函数的公式化,它不仅描述了数据点之间的相关性,还描述了响应之间的相关性。
多输出高斯过程回归的备注(2018)——引用(重点在原文):
典型的 GP 通常设计用于输出为标量的单输出场景。然而,多输出问题已经出现在各个领域,[...]。假设我们试图逼近 T 个输出 {f(t}, 1 ≤t ≤T ,一个直观的想法是使用单输出 GP (SOGP) 来分别使用相关的训练数据 D(t) = { X (t), y(t) },见图 1(a)。考虑到输出在某种程度上是相关的,单独建模它们可能会导致有价值信息的丢失。因此,越来越多的工程应用正在启动关于使用多输出 GP (MOGP) 进行代理建模的概念,如图 1(b) 所示。
MOGP的研究历史悠久,在地统计学界被称为多元克里金法或协克里金法;[...] MOGP 处理基于输出以某种方式相关的基本假设的问题。因此,MOGP 中的一个关键问题是利用输出相关性,以便输出可以利用彼此的信息,以便与单独建模相比提供更准确的预测。
具有多个输出的高斯过程的基于物理的协方差模型(2013) - 引用:
具有多个输出的过程的高斯过程分析受到以下事实的限制:与标量(单输出)情况相比,存在的协方差函数的良好类别要少得多。[...]
为多个输出找到“好的”协方差模型的困难可能会产生重要的实际后果。协方差矩阵的不正确结构会显着降低不确定性量化过程的效率,以及克里金推理中的预测效率 [16]。因此,我们认为,协方差模型可能在联合克里金法中发挥更深远的作用 [7, 17]。此论点适用于从数据推断协方差结构时,通常是这种情况。
因此,正如我所说,我的理解是 sckit-learn 并不能真正处理这种情况,尽管文档中没有提到或暗示类似的事情(在项目页面)。这似乎也是这个相关 SO 线程以及关于 GPML (Matlab) 工具箱的CrossValidated 线程中的结论。
话虽如此,除了选择简单地分别对每个输出进行建模(这不是一个无效的选择,只要您记住您可能会从您的 3-D 输出元素之间的相关性中丢弃有用的信息),至少有一个 Python 工具箱似乎能够对多输出 GP 进行建模,即runlmc(论文、代码、文档)。
推荐阅读
- c# - 为什么我不能在 Visual Studio 中移动 Windows 窗体?
- python - 从 python 在符号链接目录中运行 Makefile
- c# - 转到行/循环切换语句?
- rust - Rust - 类型的值不能从 `std::iter::Iterator<>` 构建
- c++ - c ++:原子变量的值在保存在局部变量中时无效
- .net - .net 核心网络应用程序 docker 映像如何在 Mac OS 上运行?
- css - 在导航栏中以小分辨率对齐搜索输入和提交按钮时遇到问题
- json - 使用 WireMock 对 POST 请求使用 JSON 模式检查
- ios - 快速将数据转换为 UnsafeRawPointer,反之亦然
- javascript - 为什么我不能使用 Cordova 发送 XHR 请求?