"世界上绝大多数数据都没有标签。
真正的智能,不是在已知答案中选择,而是在混沌中发现秩序。"
------无监督学习的哲学
一、为什么需要无监督学习?
在前七章中,我们系统学习了监督学习 (Supervised Learning)的核心范式:给定输入 x \mathbf{x} x 和对应标签 y y y,学习映射 f : x ↦ y f: \mathbf{x} \mapsto y f:x↦y。无论是线性回归、决策树,还是神经网络,都依赖于标注数据这一稀缺资源。
然而,现实世界的数据绝大多数是未标注的:
- 用户浏览日志(只有行为,没有"好/坏"标签);
- 医学影像(只有图像,没有诊断结论);
- 社交网络(只有连接关系,没有群体划分);
- 传感器时序(只有数值流,没有异常标记)。
获取高质量标签往往成本高昂、耗时漫长,甚至涉及伦理问题(如心理状态标注)。于是,无监督学习 (Unsupervised Learning)应运而生------它试图在没有标签的情况下,从数据本身发现隐藏结构、模式或表示。
🎯 本章目标:
- 理解无监督学习的三大核心任务:聚类、降维、密度估计;
- 深入掌握 K-Means、高斯混合模型(GMM)、主成分分析(PCA)、t-SNE 等经典算法;
- 从概率图模型视角统一理解生成式方法;
- 动手实现关键算法并可视化其效果;
- 探讨无监督学习在特征工程、异常检测、预训练中的实际应用;
- 辩证看待"无监督"的局限性与未来方向。
二、无监督学习的三大范式
无监督学习虽无统一目标函数,但可归纳为三类核心任务:
2.1 聚类(Clustering):发现数据分组
目标:将相似样本归为一类,不同类之间差异显著。
- 输入: { x 1 , x 2 , . . . , x n } ⊂ R d \{\mathbf{x}_1, \mathbf{x}_2, ..., \mathbf{x}_n\} \subset \mathbb{R}^d {x1,x2,...,xn}⊂Rd
- 输出:每个样本的簇标签 c i ∈ { 1 , 2 , . . . , K } c_i \in \{1, 2, ..., K\} ci∈{1,2,...,K}
典型应用:
- 客户细分(高价值 vs 低活跃);
- 图像分割(天空、建筑、人物);
- 文档主题聚类。
2.2 降维(Dimensionality Reduction):压缩与可视化
目标 :将高维数据映射到低维空间(通常 d ′ ≪ d d' \ll d d′≪d),同时保留重要结构。
- 输入: X ∈ R n × d \mathbf{X} \in \mathbb{R}^{n \times d} X∈Rn×d
- 输出: Z ∈ R n × d ′ \mathbf{Z} \in \mathbb{R}^{n \times d'} Z∈Rn×d′,其中 d ′ = 2 d' = 2 d′=2 或 3 3 3 常用于可视化
典型应用:
- 可视化高维数据(如单细胞 RNA-seq);
- 去噪与压缩(减少存储与计算开销);
- 作为监督学习的预处理步骤(缓解维度灾难)。
2.3 密度估计(Density Estimation):建模数据分布
目标 :估计数据的概率密度函数 p ( x ) p(\mathbf{x}) p(x)。
- 输入:样本 { x i } \{\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 } , { c i } ∑ k = 1 K ∑ i : c i = k ∥ x i − μ 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 ∈ R d \mu_k \in \mathbb{R}^d μk∈Rd:第 k k k 个簇的质心;
- c i ∈ { 1 , . . . , K } c_i \in \{1, ..., K\} ci∈{1,...,K}:样本 i i i 的簇分配。
算法流程(Lloyd 算法)
- 初始化 :随机选择 K K K 个质心 μ 1 , . . . , μ K \mu_1, ..., \mu_K μ1,...,μK;
- E 步 (Expectation):将每个样本分配给最近的质心:
c i = arg min k ∥ x i − μ k ∥ 2 c_i = \arg\min_{k} \|\mathbf{x}_i - \mu_k\|^2 ci=argkmin∥xi−μk∥2 - M 步 (Maximization):更新质心为簇内样本均值:
μ k = 1 ∣ C k ∣ ∑ i ∈ C k x i \mu_k = \frac{1}{|C_k|} \sum_{i \in C_k} \mathbf{x}_i μk=∣Ck∣1i∈Ck∑xi - 重复 2--3 直至收敛(质心不再变化或损失下降小于阈值)。
✅ 优点 :简单、高效、易于实现;
❌ 缺点:
- 需预先指定 K K K;
- 对初始值敏感(可能陷入局部最优);
- 假设簇为凸形且大小相近(无法处理月牙形等非凸簇)。
实践技巧
- 多次随机初始化:取 WCSS 最小的结果;
- K 的选择:肘部法则(Elbow Method)或轮廓系数(Silhouette Score);
- 标准化:对不同量纲的特征进行归一化(如 StandardScaler)。
python
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 提供软分配(每个样本属于各簇的概率)。
模型假设
数据由 K K K 个高斯分布混合生成:
p ( x ) = ∑ k = 1 K π k N ( 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:第 k k k 个高斯的均值;
- Σ k \boldsymbol{\Sigma}_k Σk:协方差矩阵(可全、对角或球形)。
参数学习:EM 算法
由于存在隐变量(样本所属的簇 z i ∈ { 1 , . . . , K } z_i \in \{1,...,K\} zi∈{1,...,K}),使用期望最大化(Expectation-Maximization, EM)算法:
-
E 步 :计算后验概率(责任度):
γ ( z i k ) = p ( z i = k ∣ x i ) = π k N ( x i ∣ μ k , Σ k ) ∑ j = 1 K π j N ( x i ∣ μ 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 = 1 n ∑ i = 1 n γ ( z i k ) \pi_k = \frac{1}{n} \sum_{i=1}^{n} \gamma(z_{ik}) πk=n1i=1∑nγ(zik)
μ k = ∑ i = 1 n γ ( z i k ) x i ∑ i = 1 n γ ( z i k ) \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 = 1 n γ ( z i k ) ( x i − μ k ) ( x i − μ k ) ⊤ ∑ i = 1 n γ ( z i k ) \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 优势:
- 提供概率解释;
- 可拟合椭圆、倾斜等非球形簇;
- 自然支持异常检测(低概率样本)。
python
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 ∈ R n × d \mathbf{X} \in \mathbb{R}^{n \times d} X∈Rn×d,协方差矩阵为:
C = 1 n X ⊤ X \mathbf{C} = \frac{1}{n} \mathbf{X}^\top \mathbf{X} C=n1X⊤X
PCA 寻找单位向量 w \mathbf{w} w,最大化投影方差:
max ∥ w ∥ = 1 Var ( X w ) = w ⊤ C w \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 的最大特征值对应的特征向量。
对前 k k k 个主成分,投影矩阵 W k ∈ R d × k \mathbf{W}_k \in \mathbb{R}^{d \times k} Wk∈Rd×k 由前 k k k 大特征值对应的特征向量组成。
降维后表示:
Z = X W k \mathbf{Z} = \mathbf{X} \mathbf{W}_k Z=XWk
✅ PCA 本质 :对数据进行正交变换,保留最大信息(方差)。
重建与解释方差比
- 解释方差比 :第 i i i 个主成分解释的方差占比为 λ i / ∑ j λ j \lambda_i / \sum_j \lambda_j λi/∑jλj
- 重建误差 : ∥ X − Z W k ⊤ ∥ F 2 = ∑ i = k + 1 d λ 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
python
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)通过保留局部相似性实现非线性降维。
核心思想
-
在高维空间,计算样本 i i i 与 j j j 的相似度 (以 i i i 为中心的高斯核):
p j ∣ i = exp ( − ∥ x i − x j ∥ 2 / ( 2 σ i 2 ) ) ∑ k ≠ i exp ( − ∥ x i − x k ∥ 2 / ( 2 σ i 2 ) ) 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))对称化: p i j = p j ∣ i + p i ∣ j 2 n p_{ij} = \frac{p_{j|i} + p_{i|j}}{2n} pij=2npj∣i+pi∣j
-
在低维空间(如 2D),用学生 t 分布 (自由度=1,即 Cauchy 分布)定义相似度:
q i j = ( 1 + ∥ z i − z j ∥ 2 ) − 1 ∑ k ≠ l ( 1 + ∥ z k − z l ∥ 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 散度:
min Z KL ( P ∥ Q ) = ∑ i ≠ j p i j log p i j q i j \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 ( n 2 ) O(n^2) O(n2));
- 不能保留全局距离(簇间距离无意义);
- 对超参(perplexity)敏感。
python
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∣μ,Σ)
参数通过最大似然估计:
μ = 1 n ∑ i = 1 n x i , Σ = 1 n ∑ i = 1 n ( x i − μ ) ( x i − μ ) ⊤ \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 ) = 1 n h d ∑ i = 1 n K ( x − x i h ) \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(⋅):核函数(如高斯核);
- h h h:带宽(bandwidth),控制平滑程度。
✅ KDE 优势 :灵活、无模型假设;
❌ 缺点 :维度灾难( d > 5 d > 5 d>5 时效果差)。
5.3 基于深度学习的密度估计
现代方法如 Normalizing Flows、**Variational Autoencoders **(VAE)、**Generative Adversarial Networks **(GAN) 可建模复杂高维分布,但超出本章范围。
六、动手实战:端到端无监督分析流程
我们将使用鸢尾花数据集(Iris)演示完整流程。
python
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 降维可:
- 减少过拟合;
- 加速训练;
- 去除噪声。
python
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):高重构误差视为异常。
python
# 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 核心挑战
- 无明确优化目标:不同算法优化不同准则,结果可能不一致;
- 超参敏感 :如 K K K、perplexity、带宽等需人工调整;
- 可解释性弱:降维后的轴无明确语义;
- 维度灾难:高维下距离失效,密度估计困难。
9.2 未来方向
- 自监督学习:将无监督任务转化为监督任务(如预测旋转角度);
- 对比学习:学习不变表示(同一图像的不同增强视为正样本);
- 生成模型:VAE、GAN、Diffusion Models 用于高质量样本生成;
- 图神经网络:在图结构上进行无监督表示学习(如 Node2Vec)。
✅ 趋势 :无监督学习正与深度学习深度融合,成为表示学习(Representation Learning)的核心。
十、结语:在混沌中寻找秩序
无监督学习教会我们:数据本身蕴含结构,只需合适的透镜去观察。
它不提供确定答案,而是提出假设------"这些样本可能属于同一类"、"数据可能位于这个低维流形上"。
这种探索精神,正是科学发现的本质。
下一篇文章,我们将进入模型评估与验证的领域------那里有偏差-方差权衡、交叉验证、A/B 测试,是确保模型可靠落地的关键。
但在那之前,请记住:
真正的洞察,往往始于对数据本身的敬畏与好奇。