Skip to content
知识

/knowledge/clustering

聚类

在无人标注的数据中找出自然的分组。没有正确答案可供学习——只有早已存在、等待被发现的结构。

学于
多元统计——聚类数据科学硕士(83/H1)
时间
墨尔本大学,2023–2024
应用于
分群 · 探索性分析
阅读 / 复习
约 16 分钟阅读2026-06-25

大多数机器学习是有监督的——你有带标签的样本可供学习。聚类则相反:没有 标签,没有正确答案,只有数据,任务是发现藏在其中的自然分组。哪些客户行为相似?哪些 文档讲的是同一件事?哪些地区共享某种模式?聚类回答这些问题,而无需任何人事先定义这些 分组。

它是无监督学习的招牌例子,并与 PCA 页直接成对:先降维, 再在更干净的低维空间里聚类。本页从第一性原理构建两个主力——k-means 与层次聚类——并 坦诚地说明各自何时会骗你。

01

在没有标签的情况下找出分组

一个是一组点,它们彼此之间比与簇外的点更相似。这就是全部目标:让组内 相似度最大、组间差异最大。因为没有真实标签,聚类是真正探索性的——你是在对结构提出 假设,而不是预测一个已知的目标。

这份自由也是难处所在。一个数据集并不存在唯一正确的聚类——「正确」答案取决于你所谓的 相似是什么意思、你要求多少个组,以及哪种算法的假设与你数据的形状相符。所以真正的功夫 不在于运行算法,而在于把这些选择做好,再对结果做合理性检验。

02

距离与相似度

聚类中的一切都建立在「两点相距多远」这一概念上。默认是欧氏距离——普通的 直线距离:

d(x,y)=i=1d(xiyi)2d(\mathbf{x}, \mathbf{y}) = \sqrt{\sum_{i=1}^{d} (x_i - y_i)^2}

但它并不总是对的。余弦相似度(向量之间的夹角)在方向比大小更重要时更好 ——也正是 NLP 页上比较文本 嵌入所用的度量。还有一个直接从 PCA 带过来的陷阱:在高维中,距离会聚集——每 一对点最终都大致等距,「最近」便不再有任何意义。

03

k-means

k-means 是最常用的聚类算法,它的吸引力在于简单。你告诉它你想要多少个簇 (kk),它便找出 kk 个中心点 (质心),并把每个点分配给离它最近的那个。形式上,它最小化各点到其簇质心 的总平方距离——即簇内平方和(也叫惯性):

J=j=1kxCjxμj2J = \sum_{j=1}^{k} \sum_{\mathbf{x} \in C_j} \lVert \mathbf{x} - \boldsymbol{\mu}_j \rVert^2

J 衡量簇有多紧凑。k-means 寻找让它最小的质心。

你无法直接最小化它,但一个极其简单的循环——Lloyd 算法——通过交替两个 步骤直到什么都不再移动来做到这点:

  1. 分配——把每个点放进离它最近的质心所属的簇。
  2. 更新——把每个质心移到现在分给它的那些点的均值处: μj=1CjxCjx\boldsymbol{\mu}_j = \frac{1}{|C_j|}\sum_{\mathbf{x}\in C_j}\mathbf{x}

每一轮只会降低 JJ,所以它总会收敛。难处在于:它收敛到的是一个局部最小值,取决于随机的初始质心,所以实践中你会跑好几次(k-means++ 初始化让起点彼此分散),保留最好的那个。它快且可扩展——这就是为什么尽管有 缺陷,它无处不在。

初始化 k 个质心分配→ 最近更新→ 均值重复至稳定完成
Lloyd 算法。从随机质心出发,k-means 交替地把点分配给最近的质心、再把每个质心移到其各点的均值——重复直到质心不再移动。

04

选择 k

k-means 要你事先挑定簇的数量,这感觉像作弊——如果你知道有哪些组,你就不需要聚类了。 两个标准工具帮你选择:

  • 肘部法——对一系列 kk 运行 k-means,把惯性 JJkk 作图。它总在下降(簇越多 拟合越紧),但改善的速率会在某一点急剧弯折——那个「肘部」——越过它,额外的簇几乎 无济于事。与 PCA 碎石图同样的肘部逻辑。
  • 轮廓系数——衡量每个点在自己簇里相对于次近簇坐得有多好;你挑选让平均值 最大的那个 kk。比肘部法更有原则,并且兼作质量检验(见下文)。

05

k-means 何时失效

k-means 悄悄地假定你的簇是圆形的、大小相近、密度相等的——因为它把空间 切成围绕质心的直边区域。当这个假设错了,它会自信地返回错误的答案:

  • 非球形的形状——两弯新月或同心圆环会被笔直地切开,因为 k-means 只会画 圆团。
  • 不等的大小或密度——一个大而稀疏的簇会被附近一个小而密集的簇吞掉。
  • 离群点——因为它用均值,少数极端的点会把质心拽离真正的中心。
  • 你必须事先指定 k——而它总会找出恰好那么多个簇,哪怕数据里一个都没有。

每一种失效都指向一个不同的工具——这就是为什么你的工具箱里需要不止一种聚类方法。

06

层次聚类

层次聚类采取一个完全不同的角度:它构建一整棵簇的树,而非单一的扁平分组, 而且你不必事先选定 kk。常见的凝聚式(自底向上) 版本很直观:

  1. 从每个点各自成一簇开始。
  2. 反复合并最近的两个簇。
  3. 继续直到一切归为一簇。

「最近」在之间(而非点之间)是什么意思,取决于连接方式的选择 ——单连接(最近的一对)、全连接(最远的一对)或平均连接——它会强烈地塑造结果。输出是 一张树状图:一棵展示每一次合并及其发生距离的树。你在某个高度「切」这棵 树,得到你想要的任意簇数——事后再读出结构,而非事先就定死。

切 → 2 个簇abcde
一张树状图。点自底向上合并成簇;每次合并的高度就是各组当时相距多远。在任意高度横切,便可读出那么多个簇。

07

基于密度的聚类

第三个家族直接修好了 k-means 的形状问题。DBSCAN 把簇定义为由稀疏区域 隔开的稠密区域:一个簇靠着把那些各自在小半径内有足够多邻居的点串联起来而生长。 因为它跟随的是密度而非到中心的距离,它能描出任意形状的簇——那些 k-means 弄坏的新月—— 并且它做到了 k-means 做不到的两件事:它自己找出簇的数量,并且把低 密度的点标记为噪声,而不是把每个点都硬塞进某个组。代价是:当簇的密度差异 很大时它会吃力,而且它有自己要调的参数。

08

评估聚类

没有标签,你怎么知道一个聚类好不好?你衡量各点是否舒服地待在它们被分到的组里。轮廓系数对每个点这样做:设 aa 为它到自己簇内其他 点的平均距离,bb 为它到最近的另一个簇的平均距离。则

s=bamax(a,b)[1,1]s = \frac{b - a}{\max(a, b)} \quad \in [-1, 1]

接近 +1 的值意味着该点在自己簇里很贴合、离别的簇很远(好);接近 0 意味着它在边界上;负值意味着它多半被分错了簇。把它 在所有点上取平均,你就有了一个单一的、无需标签的质量数字——既可用于评判一个聚类,也可 用于选择 kk。但没有任何度量能取代真正的检验:这些簇是否意味着 某件你能据以行动的事?

09

它在我工作中的体现

10

60 秒回顾