可视化模型拟合多维数据

机器算法验证 数据可视化 高斯过程
2022-03-26 10:44:36

我正在尝试使用高斯过程将平滑函数拟合到某些数据点。我正在使用scikit-learnpython 库,在我的情况下,我的输入是二维空间坐标,输出是一些转换版本以及二维空间坐标。我生成了一些虚拟测试数据并尝试为其拟合 GP 模型。我使用的代码如下:

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
import numpy as np

# Some dummy data
X = np.random.rand(10, 2)
Y = np.sin(X)

# Use the squared exponential kernel
kernel = C(1.0, (1e-3, 1e3)) * RBF(10, (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=9)
# Fit to data using Maximum Likelihood Estimation of the parameters
gp.fit(X, Y)
print(X)
# Evaluate on a test point
test = np.random.rand(1, 2)
test[:, 0] = 1.56
test[:, 1] = 0.92
y_pred, sigma = gp.predict(test, return_std=True)
print(test, np.sin(test))  # The true value
print(y_pred, sigma)  # The predicted value and the STD

我想知道是否有一种可视化模型拟合的好方法。由于我的输入和输出维度都是二维的,我不确定如何快速将其可视化,以便了解模型拟合(特别是想知道模型预测点之间的平滑度和方差)。当然,大多数在线示例都是针对一维案例的。

1个回答

我认为在你的情况下一个好的方法可能是

  1. 像现在这样在几个训练点上拟合多元 GP 模型
  2. 利用您拥有基本事实函数的事实,以便为一系列输入生成真实值和预测值。
  3. 绘制这些值范围的“边际”和“联合”输出的比较。

将二维输入准备为 Matlab 样式的网格:

delta = 0.025
x = np.arange(-1, +1, delta)
y = np.arange(-1, +1, delta)
X, Y = np.meshgrid(x, y)

从拟合的 GP 模型中为 2-DX 输入的所有组合生成预测,然后将 2-D 输出分成单独的数组以供以后使用:

test = np.stack([np.ravel(X), np.ravel(Y)], axis=1)
y_pred, sigma = gp.predict(test, return_std=True)
y_pred_fromX = y_pred[:,0].reshape(X.shape)
y_pred_fromY = y_pred[:,1].reshape(X.shape)

对于二维输出的第一维,我们将实际值和预测值绘制为等高线,轴代表二维输入:

import matplotlib.pyplot as plt

plt.figure(figsize=(10,5))
plt.subplot(121)
plt.contour(X, Y, np.sin(X), 20)
plt.title('1st dim: True')
plt.subplot(122)
plt.contour(X, Y, y_pred_fromX, 20)
plt.title('1st dim: Predicted')

在此处输入图像描述

二维输出的第二维相同:

plt.figure(figsize=(10,5))
plt.subplot(121)
plt.contour(X, Y, np.sin(Y), 20)
plt.title('2nd dim: True')
plt.subplot(122)
plt.contour(X, Y, y_pred_fromY, 20)
plt.title('2nd dim: Predicted')

在此处输入图像描述

仅关注二维输出,联合出现的散点图并不是特别有用。这里的轴是二维输出值:

plt.figure(figsize=(10,5))
plt.subplot(121)
plt.scatter(np.sin(X), np.sin(Y))
plt.title('True: scatterplot')
plt.subplot(122)
plt.scatter(y_pred_fromX, y_pred_fromY)
plt.title('Predicted: scatterplot')

在此处输入图像描述

但是Seaborn的联合图更有用。再一次,轴是二维输出值,该图表示计算的密度:

import seaborn as sns

plt.figure()
sns.jointplot(x=np.sin(X), y=np.sin(Y), kind='kde')
plt.title('True: jointplot')
plt.figure()
sns.jointplot(x=y_pred_fromX, y=y_pred_fromY, kind='kde')
plt.title('Predicted: jointplot')

在此处输入图像描述 在此处输入图像描述