如何在含3列的X_train上运行可视化代码?解决维度匹配报错
解决"ValueError: query data dimension must match training data dimension"问题
你的问题核心很明确:训练好的分类器是基于3个特征训练的,但可视化代码只生成了2个特征的输入数据——分类器期待接收3列特征,可你传给classifier.predict()的只有2列,维度不匹配自然就触发了报错。下面给你两种实用的解决思路:
方法一:固定第三列特征,做2D可视化(最常用)
如果想继续用简洁的2D图展示决策边界,我们可以把第三列特征固定为一个有代表性的值(比如均值、中位数,或者你关心的某个特定值),这样生成的网格数据就能补充成3列,和训练时的维度完全匹配。
修改后的完整代码如下:
# Visualising the Training set results (适配3列特征) from matplotlib.colors import ListedColormap import numpy as np import matplotlib.pyplot as plt X_set, y_set = X_train, y_train # 选择前两列特征做可视化,固定第三列的取值(这里用均值,你也可以换成中位数或特定值) fixed_feature = X_set[:, 2].mean() # 第三列特征的均值 # 生成前两列的网格数据 X1, X2 = np.meshgrid( np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.01), np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.01) ) # 构造3列的输入数据:前两列是网格值,第三列重复固定值以匹配长度 grid_data = np.array([ X1.ravel(), X2.ravel(), np.repeat(fixed_feature, X1.ravel().shape[0]) ]).T # 预测并绘制决策边界 plt.contourf( X1, X2, classifier.predict(grid_data).reshape(X1.shape), alpha=0.75, cmap=ListedColormap(('red', 'green')) ) # 绘制训练集样本点(仅展示前两列) plt.xlim(X1.min(), X1.max()) plt.ylim(X2.min(), X2.max()) for i, j in enumerate(np.unique(y_set)): plt.scatter( X_set[y_set == j, 0], X_set[y_set == j, 1], c=ListedColormap(('red', 'green'))(i), label=j ) plt.title(f'K-NN (Training set, 第三列特征固定为{fixed_feature:.2f})') plt.xlabel('特征1(比如Age)') plt.ylabel('特征2(比如Estimated Salary)') plt.legend() plt.show()
额外说明:
- 如果第三列是类别型特征(比如0/1的二元特征),可以直接固定为0或1,分别绘制两种情况下的2D决策边界,对比差异。
- 你也可以尝试把
fixed_feature换成第三列的最小值、最大值,观察不同取值下决策边界的变化。
方法二:3D可视化(展示完整三特征的决策边界)
如果想直观展示三个特征共同对分类结果的影响,可以用3D图绘制全维度的决策边界。代码如下:
# Visualising the Training set results (3D版本) from matplotlib.colors import ListedColormap import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D X_set, y_set = X_train, y_train # 生成三个特征的网格数据(调大step避免计算量过大) X1, X2, X3 = np.meshgrid( np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.1), np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.1), np.arange(start=X_set[:, 2].min() - 1, stop=X_set[:, 2].max() + 1, step=0.1) ) # 构造3列输入数据并预测 grid_data = np.array([X1.ravel(), X2.ravel(), X3.ravel()]).T predictions = classifier.predict(grid_data).reshape(X1.shape) # 创建3D画布 fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection='3d') # 绘制3D决策边界(用透明度区分网格点类别) ax.scatter(X1, X2, X3, facecolors=ListedColormap(('red', 'green'))(predictions), alpha=0.3) # 绘制训练集样本点 for i, j in enumerate(np.unique(y_set)): ax.scatter( X_set[y_set == j, 0], X_set[y_set == j, 1], X_set[y_set == j, 2], c=ListedColormap(('red', 'green'))(i), label=j, s=50 ) ax.set_title('K-NN (Training set - 3D Visualization)') ax.set_xlabel('特征1(Age)') ax.set_ylabel('特征2(Estimated Salary)') ax.set_zlabel('特征3') ax.legend() plt.show()
额外说明:
- 3D图支持拖动视角观察,能更全面地理解三个特征的交互影响,但计算量比2D大,所以我把
step从0.01改成了0.1,避免卡顿。 - 如果第三列是离散型特征,网格生成时可以只取该列的离散值,进一步减少计算量。
内容的提问来源于stack exchange,提问作者chao chong
相关产品推荐
相关产品推荐

