轮廓系数(Silhouette Score)量化K-Means聚类效果的核心指标

在K-Means聚类中,仅靠可视化判断聚类效果不够精准(尤其是高维数据),而轮廓系数(Silhouette Score) 是衡量聚类质量的黄金指标——它能从“同类紧致性”和“异类分离度”两个维度,用数值量化聚类的好坏,帮你客观判断K值是否合理、聚类结果是否有业务意义。

一、轮廓系数核心原理:3个维度讲透

1.1 核心定义

轮廓系数针对每个样本计算,取值范围为[-1, 1],整体轮廓系数是所有样本的均值:

  • 接近1:样本与同类别样本距离近,与异类别样本距离远,聚类效果极佳;
  • 接近0:样本处于两个类别边界,聚类模糊,类别划分无意义;
  • 接近-1:样本被错误划分到当前类别,聚类效果极差。

1.2 计算逻辑(单样本)

对单个样本i,轮廓系数s(i)的计算公式:
$$s(i) = \frac{b(i) - a(i)}{\max(a(i), b(i))}$$

  • a(i):样本i到同类别所有其他样本的平均距离(同类紧致性),值越小说明同类越紧凑;
  • b(i):样本i到最近的异类别所有样本的平均距离(异类分离度),值越大说明异类越分离;

1.3 整体轮廓系数

所有样本轮廓系数的算术平均值,即为整个聚类结果的轮廓系数,公式:
$$Silhouette Score = \frac{1}{n}\sum_{i=1}^n s(i)$$
(n为样本总数)

二、轮廓系数实战:代码落地(结合用户分群案例)

以之前的“电商用户消费行为分群”为例,完整演示如何计算、解读轮廓系数,对比不同K值的聚类效果。

2.1 完整代码(可直接复制运行)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, silhouette_samples

# 步骤1:构造用户消费数据(同之前的案例)
data = {
    '用户ID': range(1, 101),
    '月消费金额(元)': [np.random.randint(10, 200) for _ in range(30)] +
                    [np.random.randint(200, 800) for _ in range(50)] +
                    [np.random.randint(800, 2000) for _ in range(20)],
    '月消费频次(次)': [np.random.randint(1, 3) for _ in range(30)] +
                    [np.random.randint(3, 8) for _ in range(50)] +
                    [np.random.randint(8, 15) for _ in range(20)]
}
df = pd.DataFrame(data)

# 步骤2:数据标准化
features = df[['月消费金额(元)', '月消费频次(次)']]
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)

# 步骤3:计算不同K值的轮廓系数(K=2到K=6)
silhouette_scores = []
k_range = range(2, 7)
for k in k_range:
    kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
    cluster_labels = kmeans.fit_predict(features_scaled)
    # 计算整体轮廓系数
    score = silhouette_score(features_scaled, cluster_labels)
    silhouette_scores.append(score)
    print(f"K={k} 时,轮廓系数:{score:.4f}")

# 步骤4:可视化不同K值的轮廓系数
plt.figure(figsize=(8, 5))
plt.plot(k_range, silhouette_scores, marker='o', linestyle='-', color='blue')
plt.title('不同K值的轮廓系数对比')
plt.xlabel('聚类数K')
plt.ylabel('轮廓系数(Silhouette Score)')
plt.grid(alpha=0.3)
plt.axvline(x=3, color='red', linestyle='--', label='最优K=3')
plt.legend()
plt.show()

# 步骤5:可视化K=3时的样本级轮廓系数(进阶)
k=3
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
cluster_labels = kmeans.fit_predict(features_scaled)
# 获取每个样本的轮廓系数
sample_silhouette_values = silhouette_samples(features_scaled, cluster_labels)

# 绘制轮廓图
plt.figure(figsize=(10, 6))
y_lower = 10  # 初始y轴位置
for i in range(k):
    # 提取第i类的样本轮廓系数
    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 = plt.cm.viridis(float(i) / k)
    plt.fill_betweenx(np.arange(y_lower, y_upper),
                      0, ith_cluster_silhouette_values,
                      facecolor=color, edgecolor=color, alpha=0.7)
    # 标注类别
    plt.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
    y_lower = y_upper + 10  # 类别间留间距

# 绘制整体轮廓系数平均线
plt.axvline(x=silhouette_score(features_scaled, cluster_labels), 
            color="red", linestyle="--", label=f'整体轮廓系数:{silhouette_score(features_scaled, cluster_labels):.4f}')
plt.title('K=3时的样本级轮廓系数分布')
plt.xlabel('轮廓系数值')
plt.ylabel('样本所属类别')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

2.2 运行结果解读

1. 不同K值的轮廓系数输出(示例)

K=2 时,轮廓系数:0.6528
K=3 时,轮廓系数:0.7856  # 最大值,最优K值
K=4 时,轮廓系数:0.6987
K=5 时,轮廓系数:0.5842
K=6 时,轮廓系数:0.4915
  • K=3时轮廓系数最高(0.7856),说明将用户分为3类时,聚类效果最好;
  • K>3后轮廓系数持续下降,说明过度聚类(类别拆分无意义)。

2. 样本级轮廓系数图解读

  • 每个颜色块代表一个类别,块的宽度对应样本数量,横坐标是样本的轮廓系数;
  • 红色虚线是整体轮廓系数,若大部分样本的轮廓系数在虚线右侧,说明聚类质量高;
  • 若某类出现大量负轮廓系数,说明该类样本被错误划分。

三、轮廓系数的使用场景与注意事项

3.1 核心使用场景

  1. 确定最优K值:结合肘部法则(惯性值)+ 轮廓系数,避免仅靠惯性值选K的片面性;
  2. 评估聚类质量:对比不同聚类算法(如K-Means vs 层次聚类)的效果;
  3. 验证业务合理性:若轮廓系数<0.5,即使可视化效果好,也需重新调整K值或清洗数据。

3.2 避坑要点

  1. 高维数据需先降维:轮廓系数基于距离计算,高维数据(如100+特征)的距离计算无意义,需先用PCA降维到2-5维;
  2. 对异常值敏感:异常值会拉高a(i)或b(i),导致轮廓系数失真,需先清洗异常值;
  3. 非距离型数据不适用:若数据是分类特征(如性别、地区),需先编码(如One-Hot)并标准化,否则轮廓系数无意义;
  4. 不替代业务逻辑:轮廓系数高不代表业务有意义(比如K=3的轮廓系数最高,但业务上用户分4类更合理),需结合业务场景决策。

3.3 与肘部法则的配合使用

指标 核心作用 优势 劣势
惯性值(肘部法则) 衡量同类样本的紧致性 计算快,适合大规模数据 无法判断异类分离度
轮廓系数 兼顾紧致性和分离度 量化聚类整体质量 计算慢(样本数>10万时)

最佳实践:先用肘部法则缩小K值范围(如K=2-6),再用轮廓系数在该范围内选最优K值。

posted @ 2026-01-16 21:12  小帅记事  阅读(8)  评论(0)    收藏  举报