局部线性嵌入(LLE, Locally Linear Embedding)
LLE是一种无监督学习算法,基于一个假设:数据存在于一个低维流形上,这个流形在局部区域是线性的。我们希望找出一个嵌入,能够保留这些局部线性关系。
通常,我们采用k-近邻算法找到点 x x x的附近点 x 1 , . . . x k x_{1},...x_{k} x1,...xk,并假设 x x x能被它们线性表示:
x = w 1 x 1 + . . . + w k x k x=w_{1}x_{1}+...+w_{k}x_{k} x=w1x1+...+wkxk
通过LLE降维后,我们希望尽可能保留线性关系,即:
x ′ ≈ w 1 x 1 ′ + . . . + w k x k ′ x^{'}\approx w_{1}x_{1}^{'}+...+w_{k}x_{k}^{'} x′≈w1x1′+...+wkxk′
这么做抹除了较远的点之间的联系,达到降维的效果。具体地,在降维之前,数据集通常是 N N N个点,每个点在一个 D D D-维欧几里得空间中表示。也就是说,数据集可以表示为:
X = { x 1 , . . . x N } X=\left \{ x_{1},...x_{N} \right \} X={x1,...xN}, x i ∈ R D x_{i} \in \mathbb{R}^{D} xi∈RD
这里 D D D就是原始维度,通常非常高。
降维后,输出每个点在一个 d d d-维空间的嵌入表示:
Y = { y 1 , . . . y N } Y=\left \{ y_{1},...y_{N} \right \} Y={y1,...yN}, y i ∈ R d y_{i} \in \mathbb{R}^{d} yi∈Rd
注意, d d d是另一个超参数,并不等于 k k k,表示降维后的维度,通常有以下选择:
(1) d = 2 d=2 d=2或 3 3 3,用于可视化。
(2) d d d等于问题的固有维度(intrinsic dimension),即数据的潜在流形维度。
设系数组成 N × k N\times k N×k的矩阵 W W W,可解出:
w i j = ∑ t ∈ K i C j t − 1 ∑ t , s ∈ K i C t s − 1 w_{ij}=\frac{\sum_{t \in K_{i}}C_{jt}^{-1}}{\sum_{t,s\in K_{i}}C_{ts}^{-1}} wij=∑t,s∈KiCts−1∑t∈KiCjt−1,其中 C j t = ( x i − x j ) T ( x i − x t ) C_{jt}=(x_{i}-x_{j})^{T}(x_{i}-x_{t}) Cjt=(xi−xj)T(xi−xt)
点 x i x_{i} xi的 k k k-近邻组成的集合为 K i K_{i} Ki,定义损失函数为:
J ( W ) = min Y ∑ i = 1 N ∣ ∣ y i − ∑ j ∈ K i w i j y j ∣ ∣ 2 J(W)=\text{min}_{Y}\sum_{i=1}^{N}||y_{i}-\sum_{j\in K_{i}}w_{ij}y_{j}||^{2} J(W)=minY∑i=1N∣∣yi−∑j∈Kiwijyj∣∣2
s . t . ∑ j ∈ K i w i j = 1 s.t. \ \ \sum_{j\in K_{i}}w_{ij}=1 s.t. ∑j∈Kiwij=1
用矩阵表示优化目标:
Minimize: Y T M Y \text{Minimize: } Y^{T}MY Minimize: YTMY,其中 M = ( I − W ) T ( I − W ) M=(I-W)^{T}(I-W) M=(I−W)T(I−W)是一个稀疏矩阵。
Y的优化通过求解M的特征值问题实现:
M Y = λ Y MY = \lambda Y MY=λY
提取 M M M的最小的 d + 1 d+1 d+1个非零特征值对应的特征向量,构成低维嵌入(去掉第一个最小的特征向量,因为它通常是常量向量)。
代码实现
scikit-learn库中提供了此类方法:
from sklearn.manifold import LocallyLinearEmbedding
from sklearn.datasets import make_swiss_roll
import matplotlib.pyplot as plt# 生成三维的瑞士卷数据集
X, color = make_swiss_roll(n_samples=1000, noise=0.05)# 可视化原始高维数据
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
plt.title("Original 3D Swiss Roll")
plt.show()# 设置 LLE 参数
n_neighbors = 10 # 每个点的邻居数量
n_components = 2 # 降维后的目标维度# 创建 LLE 模型
lle = LocallyLinearEmbedding(n_neighbors=n_neighbors, n_components=n_components, method='standard')# 降维
X_lle = lle.fit_transform(X)# 可视化降维后的结果
plt.figure(figsize=(8, 6))
plt.scatter(X_lle[:, 0], X_lle[:, 1], c=color, cmap=plt.cm.Spectral)
plt.title("2D Embedding using LLE")
plt.xlabel("Component 1")
plt.ylabel("Component 2")
plt.show()