使用K-means预测标签绘制PCA散点图及训练标签选择正确性咨询
问题背景
所用数据集
数据集包含2个特征列feat_1、feat_2,1个真实标签列Label,共30条样本,原始数据如下:
feat_1 feat_2 Label 4.818919448 -8.88997718 0 2.239877125 -7.142062835 0 2.715454379 -9.392740116 0 1.457970779 -9.295304121 0 3.396769719 -4.696564243 0 -0.251264375 -3.11639814 0 1.553138885 -2.56360423 0 2.556077961 -1.639727669 0 3.264100784 -5.353501855 0 5.54079929 -2.810777111 0 -2.063969924 0.127805678 1 -1.691797179 0.835738844 1 -1.350084344 0.469993022 1 -1.672611658 0.873301506 1 -1.956488821 0.804911876 1 -1.529121941 1.112561558 1 -2.091905556 0.72908025 1 -1.835806179 0.801126086 1 -1.963433251 0.558394092 1 -2.576833733 -0.148751731 1 5.262121279 -0.291153029 2 4.150999653 4.60229228 2 2.538967939 5.642889255 2 9.908816157 2.380103599 2 9.876931469 2.29522071 2 6.691577612 -2.214740473 2 11.75361142 9.650193692 2 4.099660592 5.048216039 2 8.49165607 2.47194124 2 8.243607045 2.831411268 2
其中X为前两列构成的特征矩阵,y为第三列存储的样本真实标签。
现有处理流程与代码
当前处理逻辑为先对特征做PCA降维,再执行K-means聚类,实现代码如下:
from sklearn.preprocessing import StandardScaler, MinMaxScaler from sklearn.decomposition import PCA import matplotlib.pyplot as plt X = df.drop(columns=['Label']).values y = df['Label'].values pca = PCA().fit(X) x_pca = pca.fit_transform(X) from sklearn.cluster import KMeans k_means = KMeans(n_clusters=3, random_state=42) k_means = k_means.fit(x_pca) kmeans_labels = k_means.predict(x_pca) kmeans_labels target_names = ['class_0', 'class_1', 'class_2'] plt.figure(figsize=(8,6)) plot = plt.scatter(x_pca[:,0],x_pca[:,1],c=y,s=20, cmap=plt.cm.jet, linewidths=0, alpha=0.5) plt.scatter(k_means.cluster_centers_[:,0], k_means.cluster_centers_[:,1], marker="x", color='k', s=40) plt.legend(handles=plot.legend_elements()[0], labels=list(target_names)) plt.xlabel('feat_1') plt.ylabel('feat_2') plt.title('KMeans') plt.show()
可视化效果差异:
- 散点着色传入真实标签
c=y时,展示真实标签的样本分布 - 散点着色传入K-means聚类标签
c=kmeans_labels时,视觉上类别分离效果更好,展示K-means聚类的样本划分结果
咨询问题
- 用K-means预测得到的聚类标签给PCA散点图着色,这种可视化方式是否正确?
- 训练模型时,能不能直接用K-means生成的聚类标签做训练测试集划分,即执行如下代码:
X_train, X_test, y_train, y_test = train_test_split(x_pca, kmeans_labels, test_size=0.3, random_state=42)
还是必须用原始真实标签做划分,即执行如下代码:
X_train, X_test, y_train, y_test = train_test_split(x_pca, y, test_size=0.3, random_state=42)
问题解答
关于可视化方式的正确性
这种可视化方式语法和逻辑本身没有错误,但核心是要明确可视化的表达目的,不能混淆两类标签的含义:
- 如果你就是想展示K-means本身的聚类效果,观察每个样本的簇归属、簇中心位置、簇间边界形态,用
c=kmeans_labels着色完全正确,这本来就是聚类结果可视化的标准操作。你觉得这种方式下“分离效果更好”是必然结果——K-means的优化目标就是让同簇样本尽可能紧凑、异簇样本尽可能分离,用它自己输出的标签着色,自然会呈现出边界清晰的效果。 - 如果你是想对比聚类结果和真实标签的匹配度,评估无监督聚类对人工标注类别的还原能力,那就必须用
c=y着色。这时候看起来类别边界没那么规整,恰恰说明K-means生成的簇和真实类别没有完全对齐,这是无监督学习场景下的常见现象。
额外提醒:你当前代码里的坐标轴标注有误,PCA降维后的两个轴是生成的主成分(PC1、PC2),不是原始的feat_1和feat_2,需要对应修改。
关于数据集划分的标签选择
绝大多数监督训练场景下,绝对不能用K-means生成的聚类标签代替真实标签做训练测试集划分,必须使用原始真实标签y,核心原因如下:
- K-means作为无监督算法,输出的聚类标签没有真实业务语义:一方面簇的编号是随机分配的,比如算法输出的簇0可能对应真实标签的2,不存在固定映射关系;另一方面聚类结果本身就可能和真实类别分布存在偏差,比如你这份数据里,部分真实标签为2的样本和标签0的样本空间距离更近,就会被K-means归到同一个簇中。
- 如果用聚类标签代替真实标签训练监督模型,本质上是在让模型学习K-means的距离划分规则,根本没有学到数据和真实业务标签的映射关系,最后训出来的模型没有任何实际预测价值,跑出来的准确率、召回率等指标也不具备参考性。
唯一的例外场景是:你的任务本身就是纯聚类分析,不需要预测任何人工标注的真实标签,这时候可以用聚类标签做后续处理,但这不属于常规监督模型训练的范畴。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

