KMeans聚类代码单独运行正常,合并子图后异常的原因及解决方法
KMeans聚类可视化整合代码后失效的原因与修复方案
问题背景
尝试在3个数据集上运行KMeans模型并可视化聚类结果,分块单独运行模型绘图时一切正常,但将代码整合到同一代码块使用子图展示时,仅最后一个模型的可视化结果正常,另外两个完全失效。
数据集生成代码
blobsX, blobsY = make_blobs(n_samples=1000, n_features=2, random_state=177) classX, classY = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_clusters_per_class=1, random_state=177) circleX, circleY = make_circles(n_samples=1000, noise=0.3, random_state=177)
分块运行(结果正常)
分块运行时,每个数据集的聚类可视化都能正确展示:
- Blobs数据集聚类代码:
kmeans = KMeans(n_clusters=3) label = kmeans.fit_predict(blobsX) labels = np.unique(label) for i in labels: plt.scatter(blobsX[label == i , 0] , blobsX[label == i , 1] , label = i) plt.show()
运行后可清晰看到3个簇的区分效果。
- Classification数据集聚类代码:
kmeans = KMeans(n_clusters=2) label = kmeans.fit_predict(classX) labels2 = np.unique(label) for i in labels2: plt.scatter(classX[label == i , 0] , classX[label == i , 1] , label = i) plt.show()
运行后可正确区分2个簇。
- Circles数据集聚类代码:
kmeans = KMeans(n_clusters=2) label = kmeans.fit_predict(circleX) labels3 = np.unique(label) for i in labels3: plt.scatter(circleX[label == i , 0] , circleX[label == i , 1] , label = i) plt.show()
运行后可展示KMeans对环形数据的聚类结果。
整合代码(结果失效)
将所有代码整合后,仅最后一个子图正常显示,前两个子图失效:
kmeans = KMeans(n_clusters=3) label = kmeans.fit_predict(blobsX) labels = np.unique(label) kmeans = KMeans(n_clusters=2) label = kmeans.fit_predict(classX) labels2 = np.unique(label) kmeans= KMeans(n_clusters=2) label = kmeans.fit_predict(circleX) labels3 = np.unique(label) fig = plt.figure(figsize=(20,5)) ax = fig.add_subplot(131) ax2 = fig.add_subplot(132) ax3 = fig.add_subplot(133) for i in labels: ax.scatter(blobsX[label == i , 0] , blobsX[label == i , 1] , label = i) for j in labels2: ax2.scatter(classX[label == j , 0] , classX[label == j , 1] , label = j) for k in labels3: ax3.scatter(circleX[label == k , 0] , circleX[label == k , 1] , label = k) plt.show()
问题原因
核心问题是变量覆盖:所有聚类结果都存储在同一个label变量中。第一次给blobsX生成聚类标签后,第二次运行classX的聚类时,新的标签会覆盖原来的label值,第三次运行circleX的聚类时又再次覆盖。最终绘图时,前两个子图使用的都是最后一次生成的circleX的标签,用这个标签去匹配blobsX和classX的数据,自然无法正确筛选出对应簇的样本,导致可视化失效。
修复方案
为每个数据集的聚类标签分配独立的变量名,避免变量覆盖。将label分别命名为label_blobs、label_class、label_circle,绘图时对应使用各自的标签即可。
修复后的完整代码:
from sklearn.cluster import KMeans from sklearn.datasets import make_blobs, make_classification, make_circles import matplotlib.pyplot as plt import numpy as np # 生成数据集 blobsX, blobsY = make_blobs(n_samples=1000, n_features=2, random_state=177) classX, classY = make_classification(n_samples=1000, n_features=2, n_redundant=0, n_clusters_per_class=1, random_state=177) circleX, circleY = make_circles(n_samples=1000, noise=0.3, random_state=177) # 分别训练模型并保存独立的标签 kmeans = KMeans(n_clusters=3) label_blobs = kmeans.fit_predict(blobsX) labels_blobs = np.unique(label_blobs) kmeans = KMeans(n_clusters=2) label_class = kmeans.fit_predict(classX) labels_class = np.unique(label_class) kmeans= KMeans(n_clusters=2) label_circle = kmeans.fit_predict(circleX) labels_circle = np.unique(label_circle) # 创建子图并绘图 fig = plt.figure(figsize=(20,5)) ax = fig.add_subplot(131) ax2 = fig.add_subplot(132) ax3 = fig.add_subplot(133) # 绘制blobs数据集聚类结果 for i in labels_blobs: ax.scatter(blobsX[label_blobs == i , 0] , blobsX[label_blobs == i , 1] , label = i) ax.set_title("Blobs Dataset KMeans Clustering") ax.legend() # 绘制classification数据集聚类结果 for j in labels_class: ax2.scatter(classX[label_class == j , 0] , classX[label_class == j , 1] , label = j) ax2.set_title("Classification Dataset KMeans Clustering") ax2.legend() # 绘制circles数据集聚类结果 for k in labels_circle: ax3.scatter(circleX[label_circle == k , 0] , circleX[label_circle == k , 1] , label = k) ax3.set_title("Circles Dataset KMeans Clustering") ax3.legend() plt.show()
内容的提问来源于stack exchange,提问作者user15404111
相关产品推荐
相关产品推荐

