跳转至

14.7   均值聚类

社团老师不再问“谁会报名摄影社”,而是问:“能不能把同学按兴趣自然分成几类?”这次没有标准答案,只有每位同学的活动记录和兴趣分。

小率在散点图上看到几团点。均哥说,可以先试 K-Means 聚类(K-Means Clustering):先假设有 \(K\) 个簇,再反复寻找每个簇的中心。

图 14.7.0 在社团集市中自然聚到几个活动中心

K-Means 是不是先猜有几组,再让点自己靠近中心?
对。它像把同学分到离自己最近的活动风格中心。

14.7.1   两步循环:分配和更新

K-Means 的目标是让每个点离所属簇中心尽量近:

\[ \min_{\mathcal{C}_1,\ldots,\mathcal{C}_K}\sum_{k=1}^{K}\sum_{\mathbf{x}_i\in \mathcal{C}_k}\|\mathbf{x}_i-\boldsymbol{\mu}_k\|^2 \]

算法反复做两步:

  1. 分配:把每个点分到最近的中心。
  2. 更新:把每个中心移到当前簇内点的平均位置。

中心更新公式是:

\[ \boldsymbol{\mu}_k=\frac{1}{|\mathcal{C}_k|}\sum_{\mathbf{x}_i\in \mathcal{C}_k}\mathbf{x}_i \]

14.7.2   K-Means 偏爱圆形簇

K-Means 默认“簇像围绕中心的一团球”。如果数据是月牙形、环形、密度差异很大,K-Means 可能切得很别扭。

数据形状 K-Means 表现
圆形、大小接近 通常不错
月牙形、长条形 容易切错
密度差异大 稀疏簇可能被吞掉
高维稀疏 距离可能失真

聚类结果不是天然类别

K-Means 一定会分出 \(K\) 组,但这些组是否有业务意义,要回到场景中解释和验证。


14.7.3   K 要靠证据选择

\(K\) 不是模型自动知道的。常用方法包括:

  • 肘部法:观察 inertia 随 \(K\) 增加何时下降变慢。
  • 轮廓系数(Silhouette Score):看点在本簇内是否近、和别簇是否远。
  • 场景约束:比如社团活动只能设计 3 类推荐包。
inertia 会随着 K 变大一直下降,所以不能只盯最低值。
对。K 越多越能贴数据,但不一定更有解释价值。

14.7.4   用 Python 做聚类

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

X, _ = make_blobs(n_samples=400, centers=3, cluster_std=1.2, random_state=2026)
X = StandardScaler().fit_transform(X)

for k in [2, 3, 4, 5]:
    model = KMeans(n_clusters=k, n_init="auto", random_state=2026)
    labels = model.fit_predict(X)
    score = silhouette_score(X, labels)
    print(f"K={k}: silhouette={score:.3f}, inertia={model.inertia_:.1f}")

小率的笔记本

K-Means 反复执行“分配到最近中心”和“更新中心”。它简单快速,适合近似圆形、尺度相近的簇;但要提前选 K,且聚类结果需要业务解释。