目 录CONTENT

文章目录

使用轮廓分析评估 K-均值聚类

Administrator
2025-11-25 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://machinelearningmastery.com/k-means-cluster-evaluation-with-silhouette-analysis/

原文作者:Jason Brownlee


K-均值(K-means)聚类是一种流行的无监督学习算法,用于将数据点分组到预定义的 K 个簇中。选择正确的 K 值是 K-均值算法的关键挑战之一。本文将介绍一种用于评估 K-均值聚类有效性的技术,即使用轮廓分析(Silhouette Analysis)

什么是轮廓分析?

轮廓分析是一种用于评估聚类质量的技术。它量化了数据点与其自身簇内的样本的相似度,以及与其他最近邻簇的样本的差异度。轮廓系数(Silhouette Coefficient)的取值范围是 -1 到 +1

轮廓系数的计算公式如下:

$$ s(i) = \frac{b(i) - a(i)}{\max\{a(i), b(i)\} } $$

其中:

  • a(i) 是数据点 i 与其自身簇中的所有其他点之间的平均距离(即簇内距离)。

  • b(i) 是数据点 i 与其最近邻簇(即距离最近的另一个簇)中所有点的最小平均距离(即簇间距离)。

轮廓系数的解释如下:

  • 如果 s(i) 接近 +1,则表示数据点 i 与其自身簇匹配良好,并且与其他簇分离良好。这表明聚类效果很好。

  • 如果 s(i) 接近 0,则表示数据点 i 位于两个相邻簇的边界上,聚类效果不佳。

  • 如果 s(i) 接近 -1,则表示数据点 i 可能被错误地分配给了当前的簇,它更适合于相邻的簇。

如何使用轮廓分析?

轮廓分析的主要目的是帮助我们确定最佳的簇数量 K

轮廓分析的常用步骤是:

  1. 在给定的数据集上,对一系列不同的 K 值(例如,从 2 到 10)运行 K-均值聚类。

  2. 为每个 K 值计算所有数据点的平均轮廓系数。

  3. 选择具有最高平均轮廓系数的 K 值。

此外,还可以绘制轮廓图(Silhouette Plot),以更详细地了解每个簇的质量。

轮廓图的结构

轮廓图可视化了每个数据点的轮廓系数,并按簇分组。通常,轮廓图的结构如下:

  • 图的垂直线表示所有数据点的平均轮廓系数。

  • 每个簇由一组形状相似的条形表示,每个条形代表一个数据点的轮廓系数。

  • 如果所有簇的条形都位于平均线左侧或非常靠近平均线,则表示簇分离不佳或重叠。

  • 理想情况下,我们希望看到簇的条形都明显大于平均线,并且每个簇的厚度相对一致,表明簇的大小和密度相对均衡。

K-均值轮廓分析的Python实现

我们可以使用 Scikit-learn 库来实现 K-均值聚类和轮廓分析。

首先,我们需要导入必要的库并准备数据。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, silhouette_samples

# 1. 生成示例数据集
X, y = make_blobs(n_samples=500, n_features=2, centers=4, cluster_std=1, random_state=42)

然后,我们可以遍历不同的 K 值并计算平均轮廓系数。

# 2. 遍历 K 值并计算轮廓系数
range_n_clusters = [2, 3, 4, 5, 6]
avg_silhouette_scores = []

for n_clusters in range_n_clusters:
    # 运行 K-均值
    clusterer = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
    cluster_labels = clusterer.fit_predict(X)
    
    # 计算平均轮廓系数
    silhouette_avg = silhouette_score(X, cluster_labels)
    avg_silhouette_scores.append(silhouette_avg)
    
    print(f"对于 n_clusters = {n_clusters}, 平均轮廓系数为: {silhouette_avg:.4f}")

# 3. 找到最佳 K 值
optimal_k = range_n_clusters[np.argmax(avg_silhouette_scores)]
print(f"\n最佳 K 值为: {optimal_k}")

为了更直观地理解,我们可以绘制轮廓图。

# 4. 绘制轮廓图
plt.figure(figsize=(10, 8))

for i, n_clusters in enumerate(range_n_clusters):
    plt.subplot(3, 2, i + 1)
    
    # 运行 K-均值
    clusterer = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
    cluster_labels = clusterer.fit_predict(X)
    
    # 计算轮廓分数和样本分数
    silhouette_avg = silhouette_score(X, cluster_labels)
    sample_silhouette_values = silhouette_samples(X, cluster_labels)
    
    y_lower = 10
    for j in range(n_clusters):
        # 收集簇 j 的轮廓分数
        ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == j]
        
        ith_cluster_silhouette_values.sort()
        
        color = plt.cm.Spectral(float(j) / n_clusters)
        plt.fill_betweenx(np.arange(y_lower, y_lower + ith_cluster_silhouette_values.shape[0]),
                          0, ith_cluster_silhouette_values,
                          facecolor=color,
                          edgecolor=color,
                          alpha=0.7)
        
        # 标记簇 j 的轮廓系数的平均值
        plt.text(-0.05, y_lower + 0.5 * ith_cluster_silhouette_values.shape[0], str(j))
        
        # 计算下一个簇的起始位置
        y_lower += ith_cluster_silhouette_values.shape[0] + 2
        
    plt.title(f"K={n_clusters} 的轮廓图")
    plt.xlabel("轮廓系数值")
    plt.ylabel("簇索引")
    
    # 绘制平均轮廓线
    plt.axvline(x=silhouette_avg, color="red", linestyle="--")
    
    plt.text(0.05, 0.95, f'Avg Score: {silhouette_avg:.2f}', transform=plt.gca().transAxes, fontsize=10, verticalalignment='top')
    
    plt.yticks([]) # 隐藏 Y 轴标签

plt.tight_layout()
plt.show()

在上面的输出中,我们可以比较不同 K 值的平均轮廓系数。通常,最高平均轮廓系数对应的 K 值是最佳选择。同时,观察轮廓图可以帮助我们确认簇的质量和分离度。

总结

轮廓分析提供了一种强大的、基于距离的指标来评估 K-均值聚类的结果。通过观察平均轮廓系数和轮廓图,数据科学家可以更科学地确定数据集中的自然簇数 K,从而提高聚类模型的有效性。尽管轮廓分析是一个有用的工具,但最好结合其他方法(如肘部法则)进行综合判断。




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区