跳至内容

轮廓系数:如何评估聚类质量

一份关于轮廓系数的实操指南,涵盖公式、解读区间、scikit-learn 示例、如何用于选择合适簇数,以及与其他聚类指标的比较。
更新 2026年7月31日  · 12分钟

用 AI 探索

在 ChatGPT 中打开在 Claude 中打开在 Perplexity 中打开

训练完一个聚类模型后,如何判断这些簇是否“好”?

没有放之四海而皆准的答案。在传统的监督学习中,您可以将预测与真实标签对比并得到准确率。但聚类不行。您选了 k=5,但是否换一个 k 会更好?没有标签,您无法判断算法是真的发现了结构,还是只是把数据随意切成几块。

轮廓系数就是您要找的度量。它衡量每个点相对于次近簇而言,与其被分配簇的匹配程度,是最常用的指标之一。它不需要标签,而且容易解读。

本文将带您理解其公式与解读方式,给出基于 scikit-learn 的 Python 示例,并讨论何时适用、何时并非最佳选择。

刚接触聚类?阅读我们的scikit-learn k-Means 聚类入门教程,了解算法原理及其在 Python 中的用法。

什么是轮廓系数?

轮廓系数是介于 -1 到 1 之间的数值,用来衡量每个点与其所属簇的贴合程度。

该数值反映两方面:

  1. 该点与其所在簇内其他点的接近程度
  2. 该点与最近的其他簇之间的远离程度

若某点稳居其簇内部并远离其他簇,得分就高。若位于边界,距离相邻簇比距离本簇还近,得分就低。

简而言之,轮廓系数体现了两种平衡:簇内点的紧密程度与簇间的分离程度。两者同样重要。仅簇内紧密但簇彼此重叠并无意义;仅簇间分离良好但簇内松散也不理想。

Well-separated clusters compared with overlapping clusters

良好分离的簇 vs. 重叠的簇

分数越高,簇定义越清晰。接近 1 表示点在本簇内分布紧密且远离其他簇;接近 0 表示簇间有重叠或边界模糊;负值表示该点距离另一个簇更近,可能被误分配。

轮廓系数的工作原理

每个点都有自己的轮廓系数,该分数由两种距离决定。

第一种是该点与其所属簇内其他点的平均距离。距离小则说明靠近同簇其他点;距离大则说明与本簇的联系较松散。

第二种是该点与最近邻簇内各点的平均距离。距离大说明与其他簇分离明显;距离小则说明靠近边界。

Distance of a point to the clusters

某点到各簇的距离

轮廓值比较这两个数。深处本簇且远离他簇的点得分高;在边界附近的点得分低;更靠近他簇的点得分为负。

要记住,单独看其中任一距离都不够。

紧凑的簇也可能紧挨另一个簇;分离良好的簇内部也可能分散。两种距离兼顾,才能信任分配结果。

轮廓系数公式

单个点的公式如下:

Silhouette score formula

轮廓系数公式

其中:

  • a 为该点到同簇内所有其他点的平均距离

  • b 为该点到最近邻簇中所有点的平均距离

该公式用二者之差 ba 的差,除以二者较大者。

通常可按以下思路解读分数:

  • b 远大于 a该点远离他簇且接近本簇。分子近似 b,分母也是 b,得分接近 1

  • a 远大于 b该点更接近他簇而非本簇。分子为接近 -a 的较大负数,分母为 a,得分接近 -1

  • ab 大致相等:该点位于两簇边界。分子接近 0,分数也接近 0

更多细节如下。

如何解读轮廓系数

以下是一个大致的解读指南:

  • 接近 1: 点稳居其簇内部,且远离其他簇
  • 约 0.7: 聚类较好,簇彼此可区分,点也靠近同簇其他点
  • 约 0.5: 聚类尚可,簇间存在一定重叠,但仍能区分
  • 接近 0: 簇重叠或边界不清,结构可能并不真实
  • 低于 0: 点更接近错误的簇。可能是簇数选择不当,或数据本就不易聚类。

上述阈值只是粗略参考。何为“好”的轮廓系数取决于具体数据集。

稀疏且高维的数据,即使聚类不错,分数也常偏低;密集且分离良好的数据,分数可能高于 0.7。应在同一数据集上比较不同模型的分数,而非对照通用阈值。

如何计算轮廓系数

轮廓系数按点逐个计算。以下以单个点为例说明。

步骤 1: 计算 a,即该点到同簇内其他各点的平均距离。若该点所在簇还有 4 个点,距离分别为 1.2、1.5、1.0、1.3:

Silhouette score calculation (1)

轮廓系数计算(1)

步骤 2: 找到最近的邻近簇(除本簇外,对该点的平均距离最低者)。然后计算 b,即该点到该簇内所有点的平均距离。若最近簇有 5 个点,与该点的距离为 2.4、2.8、3.0、2.6、2.7:

Silhouette score calculation (2)

轮廓系数计算(2)

步骤 3:ab 代入公式:

Silhouette score calculation (3)

轮廓系数计算(3)

步骤 4: 对数据集中的每个点重复上述过程。该次聚类的整体轮廓系数为所有点分数的平均值。

Python 中的轮廓系数示例

Scikit-learn 在 sklearn.metrics 中提供了两个计算轮廓系数的函数:

  • silhouette_score() 返回整个聚类的平均分数

  • silhouette_samples() 返回每个点的分数

以下是在合成数据集上配合 KMeans 的用法:

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, silhouette_samples

# Synthetic data with 4 clusters
X, _ = make_blobs(n_samples=500, centers=4, cluster_std=1.0, random_state=42)

# Clustering model
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)

# Overall silhouette score
score = silhouette_score(X, labels)
print(f"Overall silhouette score: {score:.3f}")

# Per-point silhouette values
sample_scores = silhouette_samples(X, labels)
print(f"First 5 point scores: {sample_scores[:5]}")

运行以上代码片段,您将得到如下输出:

Python example output

Python 示例输出

整体得分 0.791 表示这四个簇定义清晰、彼此分离良好。

逐点分数便于对每个数据点进行分析。

单点分数高的点稳居其簇内部;分数低或为负的点位于边界或被误分配,这有助于识别离群点或复核边界样本。

选择最优簇数

轮廓系数最常见的用途之一是为 KMeans 选择合适的 k

操作包含三步:

  1. 针对一系列 k 值拟合 KMeans
  2. 计算每次拟合的轮廓系数
  3. 选择分数最高的 k

对应代码如下:

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score

X, _ = make_blobs(n_samples=500, centers=4, cluster_std=1.0, random_state=42)

# Fit KMeans for k=2 to k=10 and keep track of the silhouette score for each
k_values = range(2, 11)
scores = []
for k in k_values:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = kmeans.fit_predict(X)
    scores.append(silhouette_score(X, labels))
    print(f"k={k}: silhouette = {scores[-1]:.3f}")

对于每个 k,您会看到类似这样的分数输出:

Silhouette score across different values of k

不同 k 值下的轮廓系数

最高分数出现在 k=4。这就是应选择的值。

需要注意的是,轮廓系数并不能替代领域知识。若业务需要 5 个客户细分,而轮廓系数在 4 时最高,也别立刻选 4。该指标展示的是数据结构最清晰的地方,但有时“正确”的簇数是与您的业务意义相符的那个。

轮廓系数与其他聚类指标的比较

轮廓系数可能是最常用的聚类评估指标,但并非唯一。以下是与其他方法的对比。

轮廓系数 vs. 肘部法

肘部法是为 KMeans 选择 k 的可视化技巧。对一系列 k 拟合模型,绘制惯性(簇内平方和)与 k 的关系曲线,选择曲线出现明显“肘部”的位置。

肘部法的优势在于快速易用。但“肘部”并不总是明显。数据嘈杂时,曲线可能很平滑,难以判断拐点。

轮廓系数为每个 k 提供了具体数值,便于更有意义的比较。虽然计算更慢,但不必依赖主观的视觉判断。

用肘部法做快速健全性检查;当您需要更可据以决策的答案时,用轮廓系数。

轮廓系数 vs. Davies-Bouldin 指数

Davies-Bouldin 指数(DBI)衡量每个簇与其最相似簇之间的平均相似度。DBI 越低越好,完美分数为 0。

DBI 使用簇质心来计算相似度,因此在大数据集上比轮廓系数更快。同时,它也遵循“簇内紧凑、簇间分离”的直觉。

但 DBI 只给出整体聚类的表现。轮廓系数还能给出逐点分数,便于发现边界点和离群点。

当数据集很大且速度关键时用 DBI;当您想查看单个点时用轮廓系数。

轮廓系数 vs. Calinski-Harabasz 指数

Calinski-Harabasz 指数(CH,又称方差比准则)是簇间离散度与簇内离散度的比值。分数越高越好,且无上限。

CH 只涉及簇级统计,因此速度快,适合大数据集。与轮廓系数和 DBI 类似,它也更适用于凸且分离良好的簇。

CH 没有自然量纲,因此只能在同一数据集上比较不同模型的 CH 分数,不能跨数据集比较。

当数据集很大且需要快速得到结果时用 CH;当您需要可解释性与单点洞察时用轮廓系数。

内部指标 vs. 外部指标

上述指标(轮廓系数、DBI、CH、肘部法)都属于内部指标,只利用数据自身、无需真值标签来评估聚类。这也是真实世界聚类问题(通常没有标签)的标准选择。

外部指标会将聚类分配与已知标签比较。常见的有调整兰德指数(ARI)、归一化互信息(NMI)和同质性等。当您有标签并想检验聚类算法能否还原它们时使用外部指标。

没有标签(通常如此)时用内部指标;在带标签数据上对聚类算法做基准测试时用外部指标。

以下是各指标的并列回顾:

方法 取值范围 最佳值 速度 适用场景
轮廓系数 -1 到 1 越接近 1 越好 大数据集上较慢 可解释性与逐点洞察
肘部法 0 到无穷 寻找“肘部” 快速检查
Davies-Bouldin 指数 0 到无穷 越接近 0 越好 大型数据集
Calinski-Harabasz 指数 0 到无穷 越高越好 大型、无标签数据集

轮廓系数与替代方法的比较

轮廓系数的局限性

轮廓系数有一些值得注意的局限:

  • 假设基于距离的聚类: 轮廓系数默认基于欧氏距离。它适用于 KMeans 等质心型算法,但并不适配 DBSCAN 等基于密度、形状任意且无明确质心的方法
  • 更适合小且分离良好的簇: 该指标偏好紧密、近似球形、彼此遥远的簇。若数据中的簇彼此接近或重叠,即使聚类正确,分数也会偏低
  • 不擅长不规则簇形: 真实世界的簇不总是凸的。若您的数据并非如此,尽管分配正确,簇的轮廓系数也可能较低
  • 大数据集上的计算代价: 计算轮廓系数需要点对点的两两距离,复杂度为 O(n^2)。在上百万点的数据集上,成本会很高
  • 对距离度量的敏感性:选择欧氏、曼哈顿、余弦或其他度量都会影响分数。若数据不符合欧氏假设,轮廓系数可能误导您

使用轮廓系数的最佳实践

遵循以下基本做法,轮廓系数的效果最佳:

  • 比较多种聚类方案:不要只算一个轮廓系数。请用不同的 k(或不同算法)拟合聚类,并将分数并排比较
  • 结合可视化一起查看: 单一数值讲不全故事。请绘制聚类结果,判断形状是否合理
  • 不要只为分数最高而优化: 即便问题中 5 个簇更有意义,k=2 的聚类常常会有更高分数
  • 结合领域知识: 分数告诉您数据结构何处最“干净”,领域知识告诉您何处最有用。两者并用
  • 评估多种聚类指标: 轮廓系数、DBI、CH 等从不同角度衡量质量。当它们一致时,方向正确;不一致时,请回到数据本身

结论

轮廓系数是评估聚类最直观的方法之一,因为它同时体现簇内紧密度与簇间分离度。

它按点计算,取平均后得到一个介于 -1 与 1 的数。越接近 1,簇定义越清晰;接近或低于 0,则说明该“结构”可能并不成立。

不过,轮廓系数只是起点。应将其与聚类可视化以及最重要的领域知识结合。只有当这些线索指向同一方向时,您才能更放心地信任结果。

轮廓系数是Python 无监督学习全景的一部分。立即加入课程,学习如何在无标签数据上进行聚类、变换、可视化并提炼洞察。

主题

与 DataCamp 一起学习

Courses

R 中的聚类分析

4小时
44.1K
培养对层次聚类和 k-means 聚类工作原理的直觉,并学习如何将其应用于从数据中提取洞察。
查看详情Right Arrow
开始课程
查看更多Right Arrow