如何将高斯过程回归预测数据绘制成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




