如何正确使用scikit-learn的高斯过程进行2D输入,1D输出回归?

时间:2017-01-10 15:12:03

标签: python regression gaussian

发布之前我做了很多搜索,发现this question可能正是我的问题。但是,我尝试了答案中提出的建议,但不幸的是,这并没有解决它,我无法添加评论以请求进一步解释,因为我是这里的新成员。

无论如何,我想在Python中使用带有scikit-learn的高斯过程来开始一个简单但真实的案例(使用scikit-learn文档中提供的示例)。我有一个2D输入集(8对2个参数),称为 X 。我有8个相应的输出,聚集在1D阵列 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])

我定义了一个输入测试空间 x

# Input space
x1 = np.linspace(x1min, x1max) #p
x2 = np.linspace(x2min, x2max) #q
x = (np.array([x1, x2])).T

然后我实例化GP模型,使其适合我的训练数据(X,y),并在我的输入空间 x上进行1D预测 y_pred

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()

这是我获得的:

RBF[5,5]

当我修改内核参数时,我会得到类似于上面提到的海报的内容:

RBF[10,10]

这些图甚至与原始训练点的观察结果不一致([65.1,37]的反应较低,[92.3,54]的反应最高)。

我对2D中的GP很新(不久前也开始使用Python),所以我觉得我在这里缺少一些东西......任何答案都会有所帮助,非常感谢,谢谢!

2 个答案:

答案 0 :(得分:6)

我使用scikit-learn高斯过程也相当新。但经过一番努力,我成功地实现了三维高斯过程回归。有很多一维回归的例子,但没有更高的输入维度。

也许您可以显示您正在使用的值。

我发现有时您发送输入的格式会产生一些问题。尝试将输入X格式化为:

X = np.array([param1, param2]).T

并将输出格式化为:

gp.fit(X, y.reshape(-1,1))

另外,据我所知,该实现假定平均函数m = 0。如果您尝试回归的输出呈现的平均值与0显着不同,则应将其标准化(这可能会解决您的问题)。标准化参数空间也会有所帮助。

答案 1 :(得分:2)

您正在使用两个功能来预测第三个。而不是像## # A tibble: 48 x 7 ## fecha hora pz pz_ene pz_per pz_cng zona_carga ## <date> <int> <dbl> <dbl> <dbl> <dbl> <chr> ## 1 2017-04-19 1 1064. 969. 95.4 0 ACAPULCO ## 2 2017-04-19 2 1000. 909. 91.0 0 ACAPULCO ## 3 2017-04-19 3 954. 869. 85.4 0 ACAPULCO ## 4 2017-04-19 4 940. 855. 84.4 0 ACAPULCO ## 5 2017-04-19 5 932. 848. 84.1 0 ACAPULCO ## 6 2017-04-19 6 956. 871. 85.3 0 ACAPULCO ## 7 2017-04-19 7 1025. 943. 81.8 0 ACAPULCO ## 8 2017-04-19 8 1111. 1030. 82.5 -1.55 ACAPULCO ## 9 2017-04-19 9 1422. 1310. 112. -0.21 ACAPULCO ## 10 2017-04-19 10 1497. 1389. 108. 0 ACAPULCO ## # ... with 38 more rows 这样的3D图,如果使用能够显示有关三维尺寸的信息的2D图(例如plot_surfacehist2d),通常会更清楚。这是一个使用与问题类似的数据/代码的完整示例:

pcolormesh

输出:

enter image description here

看起来很像金达,但是我的示例数据也是如此。通常,您不应期望通过这几个数据点获得特别有趣的结果。

此外,如果您确实想要表面图,则可以将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

输出:

enter image description here