基础 · 09

无监督学习:聚类与降维

没有标签也能学。k-means 找团,GMM 用概率软化边界,PCA 转一下坐标降维,t-SNE 和 UMAP 把高维数据画出来。

17 min read

没有标签的世界

前面几篇讲的分类器——SVM、决策树、线性模型——都需要标签:有人告诉模型「这个点是 A 类」。但现实里,标注数据是昂贵的:

  • 给 100 万张图片打分类标签要花几万美元。
  • 网页、书籍、代码这些文本数据天然没有「类别」。
  • 用户的点击、浏览、停留虽然海量,但没人告诉你「这个用户属于哪个群体」。

无监督学习就是在没有标签的情况下,从数据本身找出结构。两个最经典的任务:

  • 聚类——自动把数据分成几个团。不知道有几类、不知道叫什么名字,让算法自己找。
  • 降维——把高维数据投到低维,同时尽量保留信息。100 维的特征也许只有 3 维是真正承载意义的。

这两个任务的几何直觉惊人地相似:聚类是「给空间染色」(跟分类一样,只是颜色是自己发现的),降维是「换一个角度看数据」。

k-means:找 k 个中心

k-means 是最直接的聚类算法。给定 kk(你想分几组),重复两步直到收敛:

第一步,分配:把每个点划给离它最近的中心。 第二步,更新:把每个中心挪到它管辖的点的重心。

数学上,k-means 在最小化所有点到各自中心的距离之和:

J=i=1nxiμci2J = \sum_{i=1}^{n} \|\mathbf{x}_i - \boldsymbol{\mu}_{c_i}\|^2

其中 cic_i 是点 ii 被分配到的簇编号,μci\boldsymbol{\mu}_{c_i} 是那个簇的中心。每一步 JJ 都在下降,所以一定收敛。

点「下一步」看这个过程怎么跑:

迭代 0
123
点「下一步」:每个点划给最近的中心,然后中心挪到各自群落的重心。几步之后收敛——空间被切成 3 块 Voronoi 区域。

收敛后,空间被切成 kk 块——每块由「离它最近的中心」管辖。这种基于「最近邻居」划分出来的区域叫 Voronoi 图:每个区域的边界都是相邻两个中心连线的垂直平分线。在 线性代数那篇 里学的「向量距离」在这里成了划界的尺子。

k-means 有三个关键性质值得记住:

  • 初始化敏感——不同的起始中心可能收敛到不同的局部最优。k-means++ 用一个聪明的初始化策略(让第一个中心随机选、之后的中心倾向于离现有中心远的点)显著缓解这个问题,现代实现几乎都默认用它。
  • 只能找球形的团——因为用欧氏距离作为分配准则,椭圆形或弯曲形的簇它找不好。
  • 必须预设 kk——如果你不知道数据应该分几个团,这是个真问题。

选 k 的困境

k-means 不会告诉你 kk 应该是多少。常用的两个启发式:

肘部法——画 JJkk 的曲线。随着 kk 增大,JJ 单调下降,但在某个值之后下降明显放缓(曲线出现「肘」)。拐点就是一个合理的 kk

轮廓系数——对每个点算两件事:它离自己簇内其他点的平均距离,对比它离最近的别的簇里点的平均距离。系数高 = 簇内紧、簇间疏 = 这个 kk 选得好。

两个方法都不完美——没有免费的午餐。在工业实践里(比如用户分群、embedding 聚类),kk 通常由业务需求决定而不是算法决定:「我们的客服只能维护 5 个用户画像」比任何曲线拐点都更具说服力。

GMM:软分配与 EM

k-means 有一个根本的限制:它做硬分配——每个点要么完全属于簇 1,要么完全不属于。但现实中处在两个簇边界上的点「两头都像」,硬把它归给一边是信息的浪费。

高斯混合模型(GMM) 把这个问题概率化。假设数据是由 kk 个高斯分布叠加生成的:

p(x)=k=1KπkN(xμk,Σk)p(\mathbf{x}) = \sum_{k=1}^{K} \pi_k \, \mathcal{N}(\mathbf{x} \mid \boldsymbol{\mu}_k, \boldsymbol{\Sigma}_k)

其中 πk\pi_k 是混合权重(πk=1\sum \pi_k = 1),μk\boldsymbol{\mu}_kΣk\boldsymbol{\Sigma}_k 分别是第 kk 个高斯的均值和协方差矩阵。和 k-means 只用一个中心点不同,GMM 的每个分量是一个完整的椭圆——有方向、有形状、有大小。

怎么估计参数?用 EM 算法(Expectation-Maximization):

E 步(Expectation),给定当前参数,算每个点属于各高斯的后验概率 γik\gamma_{ik}。这就是「软分配」——点 ii 可以 60% 属于簇 1、30% 属于簇 2、10% 属于簇 3。

M 步(Maximization),用这些软权重重新估计 μk\boldsymbol{\mu}_kΣk\boldsymbol{\Sigma}_kπk\pi_k——本质就是加权平均和加权协方差。

EM 保证每一步都在提高数据的对数似然 logp(X)=ilogkπkN(xiμk,Σk)\log p(X) = \sum_i \log \sum_k \pi_k \mathcal{N}(\mathbf{x}_i \mid \boldsymbol{\mu}_k, \boldsymbol{\Sigma}_k)。几何直觉:EM 就像用一块「下界板」从下方逼近对数似然函数——E 步把板子抬高到紧贴当前点的曲线下侧,M 步在板子上找最高点,每轮迭代板子和真实曲线都在往上走。

点「EM 迭代」看椭圆怎么调整形状和位置:

迭代 0
123
EM 迭代:E 步估计每个点属于各高斯的概率(软分配),M 步更新椭圆的中心和形状。与 k-means 的硬分配不同,GMM 能捕获椭球形、大小不一的簇。

注意 k-means 和 GMM 的对比:

k-meansGMM
分配方式硬分配(0 或 1)软分配(概率)
簇形状只能球形椭球形
簇大小假设等大各簇方差可不同
算法Lloyd 迭代EM 算法

事实上,当所有 GMM 的协方差矩阵趋近于 σ2I\sigma^2 \mathbf{I}σ0\sigma \to 0 时,EM 退化成 k-means——软分配变硬分配,椭圆变圆。k-means 其实是 GMM 的一个极端情况。

PCA:转一下坐标

主成分分析(PCA) 不是分类也不是聚类——它是换坐标

回忆 线性代数那篇 的特征向量:对称矩阵的特征向量是它「不被旋转」的方向。PCA 做的事就是找数据协方差矩阵的特征向量——也就是数据散布最广的方向。

具体步骤:先把数据中心化,算协方差矩阵 Σ=1nXX\Sigma = \frac{1}{n} X^\top X;做特征值分解 Σ=VΛV\Sigma = V \Lambda V^\top,特征值从大到小排列;最大特征值对应的特征向量就是数据方差最大的方向——第一主成分 PC1;把数据投影到前 kk 个主成分上 Z=XVkZ = X V_k 就完成了降维。

几何直觉:PCA 就是旋转坐标系,让第一个轴对准数据伸展最远的方向。然后你可以砍掉方差小的末几个轴——它们贡献的信息少,扔掉也不太影响。

切换下面的按钮,看 60 个点从 2D 投影到 PC1 一条线上:

PC1PC2
数据沿紫色方向(PC1)散布最广。投影到 PC1 后,只丢失了很少的信息(窄方向的方差),从 2D 降到了 1D。

投影后所有点压在一条线上——从 2 维降到了 1 维。损失的只是垂直于 PC1 方向上那点方差(窄轴方向的信息)。如果原始数据确实主要沿一个方向分布,这个损失微乎其微。

PCA 还有一个工程上很有用的副产品:每个主成分保留的方差比例 = λi/jλj\lambda_i / \sum_j \lambda_j。想知道「降到 3 维到底丢了多少信息?」,看前 3 个特征值占总特征值的比例就行。实践中经常画碎石图(scree plot)——特征值从大到小排列的折线图——来选截断点。

SVD 与降维

PCA 的计算核心是奇异值分解(SVD)。对任意矩阵 XX,SVD 把它分解成三部分:

X=UΣVX = U \Sigma V^\top

VV 的列就是主成分方向(右奇异向量),Σ\Sigma 的对角元素(奇异值)衡量每个方向上数据的伸展程度,UU 是数据在各主成分上的坐标。

截断 SVD——只保留最大的 kk 个奇异值和对应的向量——就是 PCA 降维:

XUkΣkVkX \approx U_k \Sigma_k V_k^\top

这是在所有秩-kk 矩阵里,对 XX 的最优近似(Eckart–Young 定理)。「最优」的意思是 Frobenius 范数误差最小——没有任何其他 kk 维投影能保留更多信息。

这个定理解释了为什么 PCA / SVD 在降维上如此有效:它不是「某种还不错的降维」,而是数学上证明的最优线性降维

但注意关键词:线性。PCA 只会做旋转和投影。如果数据的真实结构是弯曲的流形(想象数据散布在一个瑞士卷的表面上),PCA 会把这个卷压扁成一团——而不会「展开」它。这就引出了下面的非线性降维。

t-SNE 与 UMAP

当数据有复杂的非线性结构时,需要更灵活的工具。两个最有名的:t-SNEUMAP

t-SNE(t-distributed Stochastic Neighbor Embedding)的核心思想出人意料地简单:在高维空间里对每对点算一个「相似度」,用高斯核(近的点相似度高,远的点低);然后在 2D 或 3D 空间里随机摆点,但这次用 t 分布(厚尾)来算相似度;最后调整低维坐标,让低维相似度分布尽量接近高维相似度分布——最小化 KL 散度:

DKL(PQ)=ijpijlogpijqijD_{\text{KL}}(P \| Q) = \sum_{i \neq j} p_{ij} \log \frac{p_{ij}}{q_{ij}}

为什么用 t 分布而不是高斯?这是 t-SNE 最精妙的设计——拥挤问题的解法。高维空间里中等距离的点投到 2D 后会被「挤」成一团分不开。t 分布的厚尾允许远距离的点被推得更远,给近邻腾出空间。

t-SNE 有一个关键参数 perplexity(困惑度,通常 5–50),可以理解为「每个点考虑多少个近邻」。perplexity 小 = 只看极局部结构,perplexity 大 = 兼顾更多全局关系。

UMAP(Uniform Manifold Approximation and Projection)是 t-SNE 的后来者,用图论和黎曼几何推导出类似的优化目标,但有两个工程优势:用近似最近邻算法加速,能处理百万级数据;以及保留更多全局结构——t-SNE 经常把不相关的簇随机摆在不同位置,UMAP 的簇间距离更有参考意义。

切换按钮,看同一组数据用 PCA 和 t-SNE 投出的不同效果:

01234
线性投影
同一组高维数据(模拟 5 类手写数字)的两种 2D 投影。PCA 保留全局距离但簇互相重叠;t-SNE 放大局部结构,把五个簇干净地分开——代价是簇间距离不再有意义。
PCAt-SNEUMAP
线性 / 非线性线性非线性非线性
保留什么全局方差局部邻域局部 + 部分全局
速度极快慢(O(n2)O(n^2)
主成分含义明确簇间距离无意义簇间距离有参考意义
适用场景降维预处理可视化探索可视化 + 聚类预处理

一个重要的工程提醒:t-SNE 和 UMAP 是可视化工具,不是特征工程工具。它们产出的 2D 坐标不应该喂给下游模型——投影本身是不确定的(每次跑结果不同),还会人为制造不存在的结构。正确用法:先用 PCA 降到 50 维(去噪),再用 t-SNE / UMAP 降到 2D 画图。

这个想法在前沿里