如何正确使用 scikit-learn 的高斯过程进行二维输入、一维输出回归?
How to correctly use scikit-learn's Gaussian Process for a 2D-inputs, 1D-output regression?
在发布之前我做了很多搜索并发现 this question 这可能正是我的问题。但是,我尝试了答案中提出的建议,但不幸的是这并没有解决它,而且我无法添加评论以请求进一步解释,因为我是这里的新成员。
无论如何,我想在 Python 中使用高斯过程和 scikit-learn 在一个简单但真实的案例中开始(使用 scikit-learn 文档中提供的示例)。我有一个名为 X 的 2D 输入集(8 对 2 个参数)。我有 8 个相应的输出,聚集在一维数组 y.
# Inputs: 8 points
X = np.array([[p1, q1],[p2, q2],[p3, q3],[p4, q4],[p5, q5],[p6, q6],[p7, q7],[p8, q8]])
# Observations: 8 couples
y = np.array([r1,r2,r3,r4,r5,r6,r7,r8])
我定义了一个输入测试space x:
# Input space
x1 = np.linspace(x1min, x1max) #p
x2 = np.linspace(x2min, x2max) #q
x = (np.array([x1, x2])).T
然后我实例化 GP 模型,将其拟合到我的训练数据 (X,y),并进行一维预测 y_pred 在我的输入 space x:
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)
gp.fit(X, y)
y_pred, MSE = gp.predict(x, return_std=True)
然后我制作了一个 3D 图:
fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
Xp, Yp = np.meshgrid(x1, x2)
Zp = np.reshape(y_pred,50)
surf = ax.plot_surface(Xp, Yp, Zp, rstride=1, cstride=1, cmap=cm.jet,
linewidth=0, antialiased=False)
pl.show()
这是我得到的:
当我修改内核参数时,我得到这样的东西,类似于我上面提到的海报得到的东西:
这些图甚至与原始训练点的观察结果不匹配([65.1,37] 的响应较低,[92.3,54] 的响应最高)。
我对 2D 中的 GP 相当陌生(不久前也开始 Python)所以我想我在这里遗漏了一些东西......任何答案都会有所帮助并且非常感谢,谢谢!
我也是 scikit-learn 高斯过程的新手。但经过一些努力,我成功地实现了 3-d 高斯过程回归。有很多一维回归的例子,但没有关于更高输入维度的例子。
也许您可以显示您正在使用的值。
我发现有时您发送输入的格式会产生一些问题。尝试将输入 X 格式化为:
X = np.array([param1, param2]).T
并将输出格式化为:
gp.fit(X, y.reshape(-1,1))
此外,据我了解,该实现假定均值函数 m=0。如果您尝试回归的输出呈现出与 0 显着不同的平均值,您应该对其进行归一化(这可能会解决您的问题)。标准化参数 space 也会有所帮助。
您正在使用两个特征来预测第三个特征。与 plot_surface
这样的 3D 图不同,如果您使用能够显示有关三维信息的 2D 图,例如 hist2d
或 pcolormesh
,通常会更清楚。这是一个使用 data/code 的完整示例,类似于问题中的示例:
from itertools import product
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
X = np.array([[0,0],[2,0],[4,0],[6,0],[8,0],[10,0],[12,0],[14,0],[16,0],[0,2],
[2,2],[4,2],[6,2],[8,2],[10,2],[12,2],[14,2],[16,2]])
y = np.array([-54,-60,-62,-64,-66,-68,-70,-72,-74,-60,-62,-64,-66,
-68,-70,-72,-74,-76])
# Input space
x1 = np.linspace(X[:,0].min(), X[:,0].max()) #p
x2 = np.linspace(X[:,1].min(), X[:,1].max()) #q
x = (np.array([x1, x2])).T
kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)
gp.fit(X, y)
x1x2 = np.array(list(product(x1, x2)))
y_pred, MSE = gp.predict(x1x2, return_std=True)
X0p, X1p = x1x2[:,0].reshape(50,50), x1x2[:,1].reshape(50,50)
Zp = np.reshape(y_pred,(50,50))
# alternative way to generate equivalent X0p, X1p, Zp
# X0p, X1p = np.meshgrid(x1, x2)
# Zp = [gp.predict([(X0p[i, j], X1p[i, j]) for i in range(X0p.shape[0])]) for j in range(X0p.shape[1])]
# Zp = np.array(Zp).T
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.pcolormesh(X0p, X1p, Zp)
plt.show()
输出:
看起来有点普通,但我的示例数据也是如此。一般来说,您不应该期望通过这几个数据点得到特别有趣的结果。
此外,如果您确实想要曲面图,只需将 pcolormesh
行替换为您原来的内容(或多或少):
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X0p, X1p, Zp, rstride=1, cstride=1, cmap='jet', linewidth=0, antialiased=False)
输出:
在发布之前我做了很多搜索并发现 this question 这可能正是我的问题。但是,我尝试了答案中提出的建议,但不幸的是这并没有解决它,而且我无法添加评论以请求进一步解释,因为我是这里的新成员。
无论如何,我想在 Python 中使用高斯过程和 scikit-learn 在一个简单但真实的案例中开始(使用 scikit-learn 文档中提供的示例)。我有一个名为 X 的 2D 输入集(8 对 2 个参数)。我有 8 个相应的输出,聚集在一维数组 y.
# Inputs: 8 points
X = np.array([[p1, q1],[p2, q2],[p3, q3],[p4, q4],[p5, q5],[p6, q6],[p7, q7],[p8, q8]])
# Observations: 8 couples
y = np.array([r1,r2,r3,r4,r5,r6,r7,r8])
我定义了一个输入测试space x:
# Input space
x1 = np.linspace(x1min, x1max) #p
x2 = np.linspace(x2min, x2max) #q
x = (np.array([x1, x2])).T
然后我实例化 GP 模型,将其拟合到我的训练数据 (X,y),并进行一维预测 y_pred 在我的输入 space x:
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)
gp.fit(X, y)
y_pred, MSE = gp.predict(x, return_std=True)
然后我制作了一个 3D 图:
fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
Xp, Yp = np.meshgrid(x1, x2)
Zp = np.reshape(y_pred,50)
surf = ax.plot_surface(Xp, Yp, Zp, rstride=1, cstride=1, cmap=cm.jet,
linewidth=0, antialiased=False)
pl.show()
这是我得到的:
当我修改内核参数时,我得到这样的东西,类似于我上面提到的海报得到的东西:
这些图甚至与原始训练点的观察结果不匹配([65.1,37] 的响应较低,[92.3,54] 的响应最高)。
我对 2D 中的 GP 相当陌生(不久前也开始 Python)所以我想我在这里遗漏了一些东西......任何答案都会有所帮助并且非常感谢,谢谢!
我也是 scikit-learn 高斯过程的新手。但经过一些努力,我成功地实现了 3-d 高斯过程回归。有很多一维回归的例子,但没有关于更高输入维度的例子。
也许您可以显示您正在使用的值。
我发现有时您发送输入的格式会产生一些问题。尝试将输入 X 格式化为:
X = np.array([param1, param2]).T
并将输出格式化为:
gp.fit(X, y.reshape(-1,1))
此外,据我了解,该实现假定均值函数 m=0。如果您尝试回归的输出呈现出与 0 显着不同的平均值,您应该对其进行归一化(这可能会解决您的问题)。标准化参数 space 也会有所帮助。
您正在使用两个特征来预测第三个特征。与 plot_surface
这样的 3D 图不同,如果您使用能够显示有关三维信息的 2D 图,例如 hist2d
或 pcolormesh
,通常会更清楚。这是一个使用 data/code 的完整示例,类似于问题中的示例:
from itertools import product
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
X = np.array([[0,0],[2,0],[4,0],[6,0],[8,0],[10,0],[12,0],[14,0],[16,0],[0,2],
[2,2],[4,2],[6,2],[8,2],[10,2],[12,2],[14,2],[16,2]])
y = np.array([-54,-60,-62,-64,-66,-68,-70,-72,-74,-60,-62,-64,-66,
-68,-70,-72,-74,-76])
# Input space
x1 = np.linspace(X[:,0].min(), X[:,0].max()) #p
x2 = np.linspace(X[:,1].min(), X[:,1].max()) #q
x = (np.array([x1, x2])).T
kernel = C(1.0, (1e-3, 1e3)) * RBF([5,5], (1e-2, 1e2))
gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=15)
gp.fit(X, y)
x1x2 = np.array(list(product(x1, x2)))
y_pred, MSE = gp.predict(x1x2, return_std=True)
X0p, X1p = x1x2[:,0].reshape(50,50), x1x2[:,1].reshape(50,50)
Zp = np.reshape(y_pred,(50,50))
# alternative way to generate equivalent X0p, X1p, Zp
# X0p, X1p = np.meshgrid(x1, x2)
# Zp = [gp.predict([(X0p[i, j], X1p[i, j]) for i in range(X0p.shape[0])]) for j in range(X0p.shape[1])]
# Zp = np.array(Zp).T
fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.pcolormesh(X0p, X1p, Zp)
plt.show()
输出:
看起来有点普通,但我的示例数据也是如此。一般来说,您不应该期望通过这几个数据点得到特别有趣的结果。
此外,如果您确实想要曲面图,只需将 pcolormesh
行替换为您原来的内容(或多或少):
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X0p, X1p, Zp, rstride=1, cstride=1, cmap='jet', linewidth=0, antialiased=False)
输出: