无中生有——无监督学习的原理、算法与结构发现
“世界上绝大多数数据都没有标签。
真正的智能,不是在已知答案中选择,而是在混沌中发现秩序。”
——无监督学习的哲学
一、为什么需要无监督学习?
在前七章中,我们系统学习了监督学习(Supervised Learning)的核心范式:给定输入 x\mathbf{x}x 和对应标签 yyy,学习映射 f:x↦yf: \mathbf{x} \mapsto yf:x↦y。无论是线性回归、决策树,还是神经网络,都依赖于标注数据这一稀缺资源。
然而,现实世界的数据绝大多数是未标注的:
- 用户浏览日志(只有行为,没有“好/坏”标签);
- 医学影像(只有图像,没有诊断结论);
- 社交网络(只有连接关系,没有群体划分);
- 传感器时序(只有数值流,没有异常标记)。
获取高质量标签往往成本高昂、耗时漫长,甚至涉及伦理问题(如心理状态标注)。于是,无监督学习(Unsupervised Learning)应运而生——它试图在没有标签的情况下,从数据本身发现隐藏结构、模式或表示。
🎯 本章目标:理解无监督学习的三大核心任务:聚类、降维、密度估计;深入掌握 K-Means、高斯混合模型(GMM)、主成分分析(PCA)、t-SNE 等经典算法;从概率图模型视角统一理解生成式方法;动手实现关键算法并可视化其效果;探讨无监督学习在特征工程、异常检测、预训练中的实际应用;辩证看待“无监督”的局限性与未来方向。
二、无监督学习的三大范式
无监督学习虽无统一目标函数,但可归纳为三类核心任务:
2.1 聚类(Clustering):发现数据分组
目标:将相似样本归为一类,不同类之间差异显著。
- 输入:{x1,x2,...,xn}⊂Rd\{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\} \subset \mathbb{R}^d{x1,x2,...,xn}⊂Rd
- 输出:每个样本的簇标签 ci∈{1,2,...,K}c_i \in \{1, 2, ..., K\}ci∈{1,2,...,K}
典型应用:
- 客户细分(高价值 vs 低活跃);
- 图像分割(天空、建筑、人物);
- 文档主题聚类。
2.2 降维(Dimensionality Reduction):压缩与可视化
目标:将高维数据映射到低维空间(通常 d′≪dd' \ll dd′≪d),同时保留重要结构。
- 输入:X∈Rn×d\mathbf{X} \in \mathbb{R}^{n \times d}X∈Rn×d
- 输出:Z∈Rn×d′\mathbf{Z} \in \mathbb{R}^{n \times d'}Z∈Rn×d′,其中 d′=2d' = 2d′=2 或 333 常用于可视化
典型应用:
- 可视化高维数据(如单细胞 RNA-seq);
- 去噪与压缩(减少存储与计算开销);
- 作为监督学习的预处理步骤(缓解维度灾难)。
2.3 密度估计(Density Estimation):建模数据分布
目标:估计数据的概率密度函数 p(x)p(\mathbf{x})p(x)。
- 输入:样本 {xi}\{\mathbf{x}_i\}{xi}
- 输出:密度函数 p^(x)\hat{p}(\mathbf{x})p^(x)
典型应用:
- 异常检测(低密度区域视为异常);
- 生成新样本(从 p^(x)\hat{p}(\mathbf{x})p^(x) 采样);
- 贝叶斯推理中的先验建模。
🔑 统一视角:
所有无监督方法都在回答一个问题:“数据是如何生成的?”
聚类假设数据来自多个子分布;降维假设数据位于低维流形;密度估计直接建模整体分布。
三、聚类算法详解:从 K-Means 到高斯混合模型
3.1 K-Means:几何中心的迭代优化
K-Means 是最经典的聚类算法,其目标是最小化簇内平方和(Within-Cluster Sum of Squares, WCSS):
min{μk},{ci}∑k=1K∑i:ci=k∥xi−μk∥2 \min_{\{\mu_k\}, \{c_i\}} \sum_{k=1}^{K} \sum_{i: c_i = k} \|\mathbf{x}_i - \mu_k\|^2 {μk},{ci}mink=1∑Ki:ci=k∑∥xi−μk∥2
其中:
- μk∈Rd\mu_k \in \mathbb{R}^dμk∈Rd:第 kkk 个簇的质心;
- ci∈{1,...,K}c_i \in \{1, ..., K\}ci∈{1,...,K}:样本 iii 的簇分配。
算法流程(Lloyd 算法)
- 初始化:随机选择 KKK 个质心 μ1,...,μK\mu_1, ..., \mu_Kμ1,...,μK;
- E 步(Expectation):将每个样本分配给最近的质心:
ci=argmink∥xi−μk∥2 c_i = \arg\min_{k} \|\mathbf{x}_i - \mu_k\|^2 ci=argkmin∥xi−μk∥2 - M 步(Maximization):更新质心为簇内样本均值:
μk=1∣Ck∣∑i∈Ckxi \mu_k = \frac{1}{|C_k|} \sum_{i \in C_k} \mathbf{x}_i μk=∣Ck∣1i∈Ck∑xi - 重复 2–3 直至收敛(质心不再变化或损失下降小于阈值)。
✅ 优点:简单、高效、易于实现;
❌ 缺点:需预先指定 KKK;对初始值敏感(可能陷入局部最优);假设簇为凸形且大小相近(无法处理月牙形等非凸簇)。
实践技巧
- 多次随机初始化:取 WCSS 最小的结果;
- K 的选择:肘部法则(Elbow Method)或轮廓系数(Silhouette Score);
- 标准化:对不同量纲的特征进行归一化(如 StandardScaler)。
from sklearn.cluster import KMeans from sklearn.datasets import make_blobs import matplotlib.pyplot as plt # 生成模拟数据 X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)# 训练 K-Means kmeans = KMeans(n_clusters=4, n_init=10, random_state=42) y_pred = kmeans.fit_predict(X)# 可视化 plt.scatter(X[:,0], X[:,1], c=y_pred, cmap='viridis', s=50) plt.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], c='red', marker='x', s=200, linewidths=3) plt.title("K-Means Clustering") plt.show()3.2 高斯混合模型(GMM):概率化的聚类
K-Means 是硬分配(每个样本只属于一个簇),而 GMM 提供软分配(每个样本属于各簇的概率)。
模型假设
数据由 KKK 个高斯分布混合生成:
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) p(x)=k=1∑KπkN(x∣μk,Σk)
其中:
- πk≥0,∑kπk=1\pi_k \geq 0, \sum_k \pi_k = 1πk≥0,∑kπk=1:混合权重;
- μk\boldsymbol{\mu}_kμk:第 kkk 个高斯的均值;
- Σk\boldsymbol{\Sigma}_kΣk:协方差矩阵(可全、对角或球形)。
参数学习:EM 算法
由于存在隐变量(样本所属的簇 zi∈{1,...,K}z_i \in \{1,...,K\}zi∈{1,...,K}),使用期望最大化(Expectation-Maximization, EM)算法:
- E 步:计算后验概率(责任度):
γ(zik)=p(zi=k∣xi)=πkN(xi∣μk,Σk)∑j=1KπjN(xi∣μj,Σj) \gamma(z_{ik}) = p(z_i = k \mid \mathbf{x}_i) = \frac{\pi_k \mathcal{N}(\mathbf{x}_i \mid \boldsymbol{\mu}_k, \boldsymbol{\Sigma}_k)}{\sum_{j=1}^{K} \pi_j \mathcal{N}(\mathbf{x}_i \mid \boldsymbol{\mu}_j, \boldsymbol{\Sigma}_j)} γ(zik)=p(zi=k∣xi)=∑j=1KπjN(xi∣μj,Σj)πkN(xi∣μk,Σk) - M 步:更新参数:
πk=1n∑i=1nγ(zik) \pi_k = \frac{1}{n} \sum_{i=1}^{n} \gamma(z_{ik}) πk=n1i=1∑nγ(zik)
μk=∑i=1nγ(zik)xi∑i=1nγ(zik) \boldsymbol{\mu}_k = \frac{\sum_{i=1}^{n} \gamma(z_{ik}) \mathbf{x}_i}{\sum_{i=1}^{n} \gamma(z_{ik})} μk=∑i=1nγ(zik)∑i=1nγ(zik)xi
Σk=∑i=1nγ(zik)(xi−μk)(xi−μk)⊤∑i=1nγ(zik) \boldsymbol{\Sigma}_k = \frac{\sum_{i=1}^{n} \gamma(z_{ik}) (\mathbf{x}_i - \boldsymbol{\mu}_k)(\mathbf{x}_i - \boldsymbol{\mu}_k)^\top}{\sum_{i=1}^{n} \gamma(z_{ik})} Σk=∑i=1nγ(zik)∑i=1nγ(zik)(xi−μk)(xi−μk)⊤
✅ GMM 优势:提供概率解释;可拟合椭圆、倾斜等非球形簇;自然支持异常检测(低概率样本)。
from sklearn.mixture import GaussianMixture gmm = GaussianMixture(n_components=4, covariance_type='full', random_state=42) y_prob = gmm.fit_predict(X) plt.scatter(X[:,0], X[:,1], c=y_prob, cmap='viridis', s=50) plt.title("Gaussian Mixture Model") plt.show()3.3 其他聚类方法简述
| 算法 | 核心思想 | 适用场景 |
|---|---|---|
| DBSCAN | 基于密度,自动发现簇数,可识别噪声 | 非凸簇、含噪声数据 |
| 层次聚类 | 构建树状图(Dendrogram),可任意切分 | 小数据集、需多粒度分析 |
| 谱聚类 | 利用图拉普拉斯矩阵的特征向量 | 图结构数据、复杂流形 |
四、降维技术:从线性到非线性
4.1 主成分分析(PCA):最大方差投影
PCA 是最经典的线性降维方法,其目标是找到一组正交基,使得数据在该基下的投影方差最大。
数学推导
设数据中心化后为 X∈Rn×d\mathbf{X} \in \mathbb{R}^{n \times d}X∈Rn×d,协方差矩阵为:
C=1nX⊤X \mathbf{C} = \frac{1}{n} \mathbf{X}^\top \mathbf{X} C=n1X⊤X
PCA 寻找单位向量 w\mathbf{w}w,最大化投影方差:
max∥w∥=1Var(Xw)=w⊤Cw \max_{\|\mathbf{w}\|=1} \text{Var}(\mathbf{X} \mathbf{w}) = \mathbf{w}^\top \mathbf{C} \mathbf{w} ∥w∥=1maxVar(Xw)=w⊤Cw
通过拉格朗日乘子法,得最优解为 C\mathbf{C}C 的最大特征值对应的特征向量。
对前 kkk 个主成分,投影矩阵 Wk∈Rd×k\mathbf{W}_k \in \mathbb{R}^{d \times k}Wk∈Rd×k 由前 kkk 大特征值对应的特征向量组成。
降维后表示:
Z=XWk \mathbf{Z} = \mathbf{X} \mathbf{W}_k Z=XWk
✅ PCA 本质:对数据进行正交变换,保留最大信息(方差)。
重建与解释方差比
- 解释方差比:第 iii 个主成分解释的方差占比为 λi/∑jλj\lambda_i / \sum_j \lambda_jλi/∑jλj
- 重建误差:∥X−ZWk⊤∥F2=∑i=k+1dλi\|\mathbf{X} - \mathbf{Z} \mathbf{W}_k^\top\|_F^2 = \sum_{i=k+1}^{d} \lambda_i∥X−ZWk⊤∥F2=∑i=k+1dλi
from sklearn.decomposition import PCA pca = PCA(n_components=2) X_pca = pca.fit_transform(X)print("Explained variance ratio:", pca.explained_variance_ratio_) plt.scatter(X_pca[:,0], X_pca[:,1], alpha=0.7) plt.xlabel(f"PC1 ({pca.explained_variance_ratio_[0]:.2%})") plt.ylabel(f"PC2 ({pca.explained_variance_ratio_[1]:.2%})") plt.title("PCA Projection") plt.show()4.2 t-SNE:保留局部邻域的非线性降维
PCA 是全局线性方法,无法处理流形结构(如瑞士卷)。t-SNE(t-Distributed Stochastic Neighbor Embedding)通过保留局部相似性实现非线性降维。
核心思想
- 在高维空间,计算样本 iii 与 jjj 的相似度(以 iii 为中心的高斯核):
pj∣i=exp(−∥xi−xj∥2/(2σi2))∑k≠iexp(−∥xi−xk∥2/(2σi2)) p_{j|i} = \frac{\exp(-\|\mathbf{x}_i - \mathbf{x}_j\|^2 / (2\sigma_i^2))}{\sum_{k \neq i} \exp(-\|\mathbf{x}_i - \mathbf{x}_k\|^2 / (2\sigma_i^2))} pj∣i=∑k=iexp(−∥xi−xk∥2/(2σi2))exp(−∥xi−xj∥2/(2σi2))
对称化:pij=pj∣i+pi∣j2np_{ij} = \frac{p_{j|i} + p_{i|j}}{2n}pij=2npj∣i+pi∣j - 在低维空间(如 2D),用学生 t 分布(自由度=1,即 Cauchy 分布)定义相似度:
qij=(1+∥zi−zj∥2)−1∑k≠l(1+∥zk−zl∥2)−1 q_{ij} = \frac{(1 + \|\mathbf{z}_i - \mathbf{z}_j\|^2)^{-1}}{\sum_{k \neq l} (1 + \|\mathbf{z}_k - \mathbf{z}_l\|^2)^{-1}} qij=∑k=l(1+∥zk−zl∥2)−1(1+∥zi−zj∥2)−1 - 最小化 KL 散度:
minZKL(P∥Q)=∑i≠jpijlogpijqij \min_{\mathbf{Z}} \text{KL}(P \| Q) = \sum_{i \neq j} p_{ij} \log \frac{p_{ij}}{q_{ij}} ZminKL(P∥Q)=i=j∑pijlogqijpij
✅ t-SNE 优势:能清晰分离簇,适合可视化;
❌ 缺点:计算复杂度高(O(n2)O(n^2)O(n2));不能保留全局距离(簇间距离无意义);对超参(perplexity)敏感。
from sklearn.manifold import TSNE tsne = TSNE(n_components=2, perplexity=30, random_state=42) X_tsne = tsne.fit_transform(X) plt.scatter(X_tsne[:,0], X_tsne[:,1], alpha=0.7) plt.title("t-SNE Embedding") plt.show()4.3 UMAP:更快更稳定的流形学习
UMAP(Uniform Manifold Approximation and Projection)是 t-SNE 的现代替代品:
- 基于拓扑学(流形假设)和模糊拓扑;
- 保留局部与部分全局结构;
- 计算效率更高(近似最近邻);
- 支持逆变换(从低维重建高维)。
✅ 实践建议:优先尝试 UMAP 而非 t-SNE。
五、密度估计:建模数据的生成机制
5.1 参数化方法:高斯分布族
最简单的密度估计是假设数据服从多元高斯分布:
p(x)=N(x∣μ,Σ) p(\mathbf{x}) = \mathcal{N}(\mathbf{x} \mid \boldsymbol{\mu}, \boldsymbol{\Sigma}) p(x)=N(x∣μ,Σ)
参数通过最大似然估计:
μ=1n∑i=1nxi,Σ=1n∑i=1n(xi−μ)(xi−μ)⊤ \boldsymbol{\mu} = \frac{1}{n} \sum_{i=1}^{n} \mathbf{x}_i, \quad \boldsymbol{\Sigma} = \frac{1}{n} \sum_{i=1}^{n} (\mathbf{x}_i - \boldsymbol{\mu})(\mathbf{x}_i - \boldsymbol{\mu})^\top μ=n1i=1∑nxi,Σ=n1i=1∑n(xi−μ)(xi−μ)⊤
但真实数据往往多峰、非高斯,故需混合模型(如 GMM)。
5.2 非参数化方法:核密度估计(KDE)
KDE 不假设分布形式,而是用核函数平滑样本点:
p^(x)=1nhd∑i=1nK(x−xih) \hat{p}(\mathbf{x}) = \frac{1}{n h^d} \sum_{i=1}^{n} K\left( \frac{\mathbf{x} - \mathbf{x}_i}{h} \right) p^(x)=nhd1i=1∑nK(hx−xi)
其中:
- K(⋅)K(\cdot)K(⋅):核函数(如高斯核);
- hhh:带宽(bandwidth),控制平滑程度。
✅ KDE 优势:灵活、无模型假设;
❌ 缺点:维度灾难(d>5d > 5d>5 时效果差)。
5.3 基于深度学习的密度估计
现代方法如 Normalizing Flows、**Variational Autoencoders **(VAE)、**Generative Adversarial Networks **(GAN) 可建模复杂高维分布,但超出本章范围。
六、动手实战:端到端无监督分析流程
我们将使用鸢尾花数据集(Iris)演示完整流程。
from sklearn import datasets from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans from sklearn.mixture import GaussianMixture from sklearn.decomposition import PCA from sklearn.manifold import TSNE import seaborn as sns # 1. 加载数据 iris = datasets.load_iris() X, y_true = iris.data, iris.target feature_names = iris.feature_names # 2. 标准化(对聚类和PCA至关重要!) scaler = StandardScaler() X_scaled = scaler.fit_transform(X)# 3. 聚类(K=3,已知真实类别数) kmeans = KMeans(n_clusters=3, random_state=42).fit(X_scaled) gmm = GaussianMixture(n_components=3, random_state=42).fit(X_scaled)# 4. 降维可视化 pca = PCA(n_components=2) X_pca = pca.fit_transform(X_scaled) tsne = TSNE(n_components=2, perplexity=30, random_state=42) X_tsne = tsne.fit_transform(X_scaled)# 5. 绘图对比 fig, axes = plt.subplots(2,3, figsize=(15,10))# 真实标签 axes[0,0].scatter(X_pca[:,0], X_pca[:,1], c=y_true, cmap='tab10') axes[0,0].set_title("PCA + True Labels") axes[1,0].scatter(X_tsne[:,0], X_tsne[:,1], c=y_true, cmap='tab10') axes[1,0].set_title("t-SNE + True Labels")# K-Means axes[0,1].scatter(X_pca[:,0], X_pca[:,1], c=kmeans.labels_, cmap='tab10') axes[0,1].set_title("PCA + K-Means") axes[1,1].scatter(X_tsne[:,0], X_tsne[:,1], c=kmeans.labels_, cmap='tab10') axes[1,1].set_title("t-SNE + K-Means")# GMM axes[0,2].scatter(X_pca[:,0], X_pca[:,1], c=gmm.predict(X_scaled), cmap='tab10') axes[0,2].set_title("PCA + GMM") axes[1,2].scatter(X_tsne[:,0], X_tsne[:,1], c=gmm.predict(X_scaled), cmap='tab10') axes[1,2].set_title("t-SNE + GMM") plt.tight_layout() plt.show()# 6. 评估聚类质量(无标签时用轮廓系数)from sklearn.metrics import silhouette_score print("K-Means Silhouette:", silhouette_score(X_scaled, kmeans.labels_))print("GMM Silhouette: ", silhouette_score(X_scaled, gmm.predict(X_scaled)))✅ 关键观察:PCA 保留了主要判别方向(前两个主成分解释 95%+ 方差);t-SNE 更好地分离了 setosa 类;GMM 和 K-Means 在此数据上表现接近(因簇近似球形)。
七、无监督学习的实际应用场景
7.1 特征工程:降维作为预处理
在监督学习前,用 PCA 或 UMAP 降维可:
- 减少过拟合;
- 加速训练;
- 去除噪声。
from sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestClassifier pipe = Pipeline([('pca', PCA(n_components=0.95)),# 保留 95% 方差('rf', RandomForestClassifier())]) pipe.fit(X_train, y_train)7.2 异常检测:基于密度或重构误差
- GMM:低概率样本视为异常;
- 自编码器(Autoencoder):高重构误差视为异常。
# GMM 异常检测 gmm = GaussianMixture(n_components=2).fit(X_scaled) log_probs = gmm.score_samples(X_scaled) threshold = np.percentile(log_probs,5)# 下5%为异常 anomalies = log_probs < threshold 7.3 预训练表示:无监督学习的复兴
在深度学习中,自监督学习(Self-Supervised Learning)成为无监督学习的新范式:
- 对比学习(Contrastive Learning):拉近正样本对,推开负样本对;
- 掩码语言建模(如 BERT):预测被掩盖的词;
- 图像修复:预测被遮挡的像素。
这些方法在无标签数据上预训练,再微调(Fine-tune)到下游任务,极大减少对标记数据的依赖。
八、评估无监督学习:没有标签怎么办?
无监督学习缺乏 ground truth,评估更具挑战性。
8.1 内部指标(Internal Metrics)
仅依赖数据和聚类结果:
- 轮廓系数(Silhouette Score):
s(i)=b(i)−a(i)max{a(i),b(i)} s(i) = \frac{b(i) - a(i)}{\max\{a(i), b(i)\}} s(i)=max{a(i),b(i)}b(i)−a(i)
其中 a(i)a(i)a(i) 是簇内平均距离,b(i)b(i)b(i) 是最近其他簇的平均距离。
越接近 1 越好。 - Calinski-Harabasz 指数:簇间离散度 / 簇内离散度,越大越好。
8.2 外部指标(External Metrics,若有真实标签)
- 调整兰德指数(Adjusted Rand Index, ARI);
- 归一化互信息(Normalized Mutual Information, NMI)。
8.3 可视化评估
- 降维后观察簇是否分离;
- 使用领域知识判断合理性(如“高收入+高消费”应为一类)。
九、无监督学习的局限与未来
9.1 核心挑战
- 无明确优化目标:不同算法优化不同准则,结果可能不一致;
- 超参敏感:如 KKK、perplexity、带宽等需人工调整;
- 可解释性弱:降维后的轴无明确语义;
- 维度灾难:高维下距离失效,密度估计困难。
9.2 未来方向
- 自监督学习:将无监督任务转化为监督任务(如预测旋转角度);
- 对比学习:学习不变表示(同一图像的不同增强视为正样本);
- 生成模型:VAE、GAN、Diffusion Models 用于高质量样本生成;
- 图神经网络:在图结构上进行无监督表示学习(如 Node2Vec)。
✅ 趋势:无监督学习正与深度学习深度融合,成为表示学习(Representation Learning)的核心。
十、结语:在混沌中寻找秩序
无监督学习教会我们:数据本身蕴含结构,只需合适的透镜去观察。
它不提供确定答案,而是提出假设——“这些样本可能属于同一类”、“数据可能位于这个低维流形上”。
这种探索精神,正是科学发现的本质。
下一篇文章,我们将进入模型评估与验证的领域——那里有偏差-方差权衡、交叉验证、A/B 测试,是确保模型可靠落地的关键。
但在那之前,请记住:
真正的洞察,往往始于对数据本身的敬畏与好奇。