You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将高斯过程回归预测数据绘制成3D等高线图?

高斯过程回归预测值的3D等高线图绘制报错问题

我尝试把高斯过程回归的预测均值绘制成3D等高线图,参考了Matplotlib的3D contour相关教程后写了代码,但运行后报错,想请教下代码里的问题出在哪?

我的需求是让x、y轴构成二维平面,z轴对应高斯过程的预测值,目标是做出带有分层等高线的3D图,类似那种能清晰看到不同z值区域分布的效果。

下面是我写的代码:

import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

x_train = np.array([[0,0],[2,2],[3,3]])
y_train = np.array([[200,321,417]])
xvalues = np.array([0,1,2,3])
yvalues = np.array([0,1,2,3])
a,b = np.meshgrid(xvalues,yvalues)
positions = np.vstack([a.ravel(), b.ravel()])
x_test = (np.array(positions)).T

kernel = C(1.0, (1e-3, 1e3)) * RBF(10)
gp = GaussianProcessRegressor(kernel=kernel)
gp.fit(x_train, y_train)
y_pred_test = gp.predict(x_test)

fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
x=y=np.arange(0,3,1)
X, Y = np.meshgrid(x,y)
Z = y_pred_test
cset = ax.contour(X, Y, Z, cmap=cm.coolwarm)
ax.clabel(cset, fontsize=9, inline=1)
plt.show()

问题分析与修正方案

你的代码主要有3个关键问题,导致了报错和不符合预期的结果:

  • 训练标签形状错误y_train被定义成了[[200,321,417]],是(1,3)的二维数组,但GaussianProcessRegressor.fit()要求目标变量是一维数组(形状为(n_samples,))。你需要把它改成一维的:

    y_train = np.array([200,321,417])
    
  • 预测结果形状不匹配y_pred_test是长度为16的一维数组(对应4x4网格的16个点),但ax.contour()要求Z参数是和X、Y同形状的二维数组。所以需要把预测结果重塑成4x4的二维数组:

    Z = y_pred_test.reshape(X.shape)
    
  • 网格范围不匹配:你定义的x=y=np.arange(0,3,1)只生成了[0,1,2]三个值,对应的X、Y是3x3的网格,但你的测试集是4x4的16个点(xvalues和yvalues是[0,1,2,3]),这会导致X/Y和Z的形状不匹配。需要把网格范围改成包含3:

    x=y=np.arange(0,4,1)
    

修正后的完整代码

import numpy as np
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm

x_train = np.array([[0,0],[2,2],[3,3]])
# 修正y_train为一维数组
y_train = np.array([200,321,417])
xvalues = np.array([0,1,2,3])
yvalues = np.array([0,1,2,3])
a,b = np.meshgrid(xvalues,yvalues)
positions = np.vstack([a.ravel(), b.ravel()])
x_test = (np.array(positions)).T

kernel = C(1.0, (1e-3, 1e3)) * RBF(10)
gp = GaussianProcessRegressor(kernel=kernel)
gp.fit(x_train, y_train)
y_pred_test = gp.predict(x_test)

fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
# 修正网格范围,包含0-3的四个值
x=y=np.arange(0,4,1)
X, Y = np.meshgrid(x,y)
# 重塑Z的形状为4x4
Z = y_pred_test.reshape(X.shape)
cset = ax.contour(X, Y, Z, cmap=cm.coolwarm)
ax.clabel(cset, fontsize=9, inline=1)
# 添加轴标签让图更清晰
ax.set_xlabel('X Axis')
ax.set_ylabel('Y Axis')
ax.set_zlabel('Predicted Value')
plt.show()

运行这段修正后的代码,就能得到你想要的3D等高线图了,x、y轴构成完整的4x4平面,z轴对应高斯过程的预测值,等高线也能正确分层显示。

内容的提问来源于stack exchange,提问作者santobedi

火山引擎 最新活动