我正在使用 scikit-learn 进行高斯过程回归(GPR)操作来预测数据。我的训练数据如下:
x_train = np.array([[0,0],[2,2],[3,3]]) #2-D cartesian coordinate pointsy_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(GaussianProcessRegressor
)拟合之后(这里使用了 ConstantKernel 和 RBF 的乘积作为 GaussianProcessRegressor
中的内核),可以通过以下代码行预测均值和方差/标准差:
y_pred_test, sigma = gp.predict(x_test, return_std =True)
在打印预测的均值(y_pred_test
)和方差(sigma
)时,我在控制台中获得了以下输出:
在预测值(均值)中,打印了内部数组中有三个对象的“嵌套数组”。可以推测,内部数组是每个数据源在每个 2-D 测试点位置的预测均值。然而,打印的方差仅包含一个具有 16 个对象的数组(可能是针对 16 个测试位置点)。我知道方差提供了估计不确定性的指示。因此,我期望在每个测试点获得每个数据源的预测方差。我的期望是错误的吗?我如何才能获得每个测试点上每个数据源的预测方差?这是由于代码错误吗?
回答:
嗯,你确实无意中撞上了冰山…
作为前言,让我们明确一点,方差和标准差的概念仅适用于标量变量;对于向量变量(如你这里的 3D 输出),方差的概念不再有意义,取而代之的是使用协方差矩阵(Wikipedia,Wolfram)。
继续前言,你的 sigma
的形状确实如预期的那样,根据 scikit-learn 文档 中的 predict
方法(即在你的情况下没有编码错误):
返回值:
y_mean : 数组,形状 = (n_samples, [n_output_dims])
查询点预测分布的均值
y_std : 数组,形状 = (n_samples,),可选
查询点预测分布的标准差。仅当 return_std 为 True 时返回。
y_cov : 数组,形状 = (n_samples, n_samples),可选
查询点联合预测分布的协方差。仅当 return_cov 为 True 时返回。
结合我之前关于协方差矩阵的评论,第一个选择是尝试使用参数 return_cov=True
调用 predict
函数(因为请求向量变量的方差是没有意义的);但同样,这将导致一个 16×16 的矩阵,而不是一个 3×3 的矩阵(3 个输出变量的预期协方差矩阵形状)…
澄清了这些细节后,让我们继续讨论问题的本质。
你的问题的核心在于一个在实践中和相关教程中很少提及(甚至暗示)的事情:具有多个输出的高斯过程回归是非常非平凡的,仍然是一个活跃的研究领域。可以说,scikit-learn 实际上无法处理这种情况,尽管它表面上看起来可以处理,而没有发出任何相关的警告。
让我们在最近的科学文献中寻找一些证据来支持这一说法:
具有多个响应变量的高斯过程回归(2015 年) – 引用(强调我的):
大多数 GPR 实现仅模拟单个响应变量,这是因为难以制定用于相关多个响应变量的协方差函数,这不仅描述了数据点之间的相关性,还描述了响应之间的相关性。在本文中,我们提出了一种基于…的多响应 GPR 的协方差函数的直接公式化方法。
尽管 GPR 在各种建模任务中被广泛采用,但 GPR 方法仍然存在一些未解决的问题。本文特别关注的是需要建模多个响应变量的需求。传统上,一个响应变量被视为高斯过程,多个响应被独立建模而不考虑它们的相关性。这种实用且直接的方法在许多应用中被采用(例如 [7, 26, 27]),尽管它并非理想。建模多响应高斯过程的关键在于制定协方差函数,不仅描述数据点之间的相关性,还描述响应之间的相关性。