K均值聚类与轮廓分析

机器学习领域,聚类算法是一种无监督学习方法,旨在将数据集中的样本划分为若干个簇,使得同一簇内的样本相似度高,而不同簇之间的样本相似度低。K均值聚类算法是其中一种常用的聚类方法,它通过迭代优化簇中心点来实现数据的聚类。然而,K均值聚类算法的一个关键问题是确定最优的簇数量,即如何选择合适的k值。轮廓分析提供了一种评估不同k值的方法,它通过计算轮廓系数来衡量样本点与其邻近簇的距离,从而帮助选择最佳的簇数量。

轮廓系数的取值范围在-1到1之间,接近1的值表示样本点远离邻近簇,0表示样本点位于两个邻近簇的决策边界上,而负值则可能表示样本点被错误地分配到了某个簇中。在本例中,使用轮廓分析来选择最优的簇数量。轮廓图显示,当簇数量为3、5和6时,由于存在轮廓分数低于平均值的簇以及轮廓图大小的大幅波动,这些簇数量的选择对于给定数据来说并不理想。轮廓分析在决定2和4之间的簇数量时更为模糊。

此外,通过轮廓图的厚度可以直观地观察到簇的大小。当簇数量为2时,轮廓图的大小较大,这是因为将3个子簇合并为一个大簇。然而,当簇数量为4时,所有的轮廓图大小大致相同,因此簇的大小也大致相同,这一点也可以从右侧标记的散点图中得到验证。

以下是不同簇数量下的平均轮廓分数:

For n_clusters = 2 The average silhouette_score is : 0.7049787496083262 For n_clusters = 3 The average silhouette_score is : 0.5882004012129721 For n_clusters = 4 The average silhouette_score is : 0.6505186632729437 For n_clusters = 5 The average silhouette_score is : 0.561464362648773 For n_clusters = 6 The average silhouette_score is : 0.4857596147013469

为了实现这一分析,首先使用make_blobs函数生成样本数据。这个特定的设置有一个明显的簇和3个紧密放置的簇。然后,为不同的簇数量创建子图,包括轮廓图和实际聚类形成的散点图。在轮廓图中,计算了每个样本的轮廓分数,并根据它们所属的簇对这些分数进行聚合和排序。使用不同的颜色来表示不同的簇,并在轮廓图上绘制了平均轮廓分数的垂直线。在散点图中,使用不同的颜色来表示不同的簇,并在簇中心处绘制了白色的圆圈。

以下是实现轮廓分析的Python代码示例:

import matplotlib.cm as cm import matplotlib.pyplot as plt import numpy as np from sklearn.cluster import KMeans from sklearn.datasets import make_blobs from sklearn.metrics import silhouette_samples, silhouette_score # 生成样本数据 X, y = make_blobs(n_samples=500, n_features=2, centers=4, cluster_std=1, center_box=(-10.0, 10.0), shuffle=True, random_state=1) # 定义不同的簇数量 range_n_clusters = [2, 3, 4, 5, 6] for n_clusters in range_n_clusters: # 创建子图 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 7)) # 计算轮廓分数 clusterer = KMeans(n_clusters=n_clusters, random_state=10) cluster_labels = clusterer.fit_predict(X) silhouette_avg = silhouette_score(X, cluster_labels) print("For n_clusters =", n_clusters, "The average silhouette_score is :", silhouette_avg) # 计算每个样本的轮廓分数 sample_silhouette_values = silhouette_samples(X, cluster_labels) # 绘制轮廓图 y_lower = 10 for i in range(n_clusters): ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i] ith_cluster_silhouette_values.sort() size_cluster_i = ith_cluster_silhouette_values.shape[0] y_upper = y_lower + size_cluster_i color = cm.nipy_spectral(float(i) / n_clusters) ax1.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_silhouette_values, facecolor=color, edgecolor=color, alpha=0.7) ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i)) y_lower = y_upper + 10 # 设置轮廓图的标题和标签 ax1.set_title("The silhouette plot for the various clusters.") ax1.set_xlabel("The silhouette coefficient values") ax1.set_ylabel("Cluster label") ax1.axvline(x=silhouette_avg, color="red", linestyle="--") ax1.set_yticks([]) ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1]) # 绘制散点图 colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters) ax2.scatter(X[:, 0], X[:, 1], marker=".", s=30, lw=0, alpha=0.7, c=colors, edgecolor="k") centers = clusterer.cluster_centers_ ax2.scatter(centers[:, 0], centers[:, 1], marker="o", c="white", alpha=1, s=200, edgecolor="k") for i, c in enumerate(centers): ax2.scatter(c[0], c[1], marker="$%d$" % i, alpha=1, s=50, edgecolor="k") # 设置散点图的标题和标签 ax2.set_title("The visualization of the clustered data.") ax2.set_xlabel("Feature space for the 1st feature") ax2.set_ylabel("Feature space for the 2nd feature") plt.suptitle("Silhouette analysis for KMeans clustering on sample data with n_clusters = %d" % n_clusters, fontsize=14, fontweight="bold") plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485