介绍
等距映射(Isomap,Isometric Mapping)是一种非线性降维算法,属于流形学习方法,用于在保留高维数据几何结构的前提下,将数据降到低维空间。Isomap 是对经典多维缩放(MDS,Multidimensional Scaling)的扩展,通过保留点对点之间的流形距离来实现降维。
高维空间中的数据通常位于低维流形上(如曲面或曲线)。在高维空间中,欧几里得距离可能无法准确反映数据的真实结构,而沿流形的距离(即流形距离)能够更好地描述数据点之间的关系。Isomap 的目标是:
(1)计算高维数据点之间的流形距离;
(2)使用这些流形距离在低维空间中重构数据点的位置。
流形距离
流形距离(Manifold Distance)是数据点沿其所在流形表面之间的最短路径距离。它区别于欧几里得距离,后者是在原始高维空间中测量的直线距离,而流形距离反映了数据在低维流形结构上的真实几何关系。
例如二维曲面上,欧几里得距离只能表示直线距离,而不能表示真实几何关系(曲面)。
以下是数学定义(来源GPT):
等距映射(Isomap)
建图
流形在局部上与欧几里得空间同胚(定义,局部欧几里得性),所以我们可以对每个点基于欧氏距离找出近邻点,然后建立邻接图,边权为两点间的欧几里得距离。
通常会有两个超参数,一个是最多挑选的近邻点数量
k
k
k,一个是近邻点的距离阈值
ϵ
\epsilon
ϵ。
寻找最短路和最短流形距离
在图上跑最短路算法(Floyd,Dijkstra),即可找到两个点之间的最短路程,这个路程被称为最短流形距离。
多维缩放(MDS)
在最短流形距离的基础上进行经典MDS。
多维缩放是一种经典的降维方法,旨在从高维数据中提取低维嵌入,同时尽可能保留数据点之间的距离关系。MDS 的核心目标是将高维点的距离关系映射到低维空间中,使得低维空间中的点对之间的距离与原始距离尽可能相似。
输入距离矩阵 D = [ d 12 ⋯ d 1 n ⋮ ⋱ ⋮ d n 1 ⋯ d n n ] D=\begin{bmatrix} d_{12} & \cdots & d_{1n}\\ \vdots & \ddots & \vdots\\ d_{n1} & \cdots & d_{nn}\end{bmatrix} D= d12⋮dn1⋯⋱⋯d1n⋮dnn
指定低维空间维度为 m m m
输出一个 n × m n\times m n×m的矩阵 Y = [ y 1 ⋮ y n ] Y=\begin{bmatrix}y_{1} \\\vdots \\y_{n}\end{bmatrix} Y= y1⋮yn ,其中 y i ∈ R m y_{i} \in \mathbb{R}^{m} yi∈Rm,表示一个低维嵌入。
损失函数 S ( Y ) = ∑ i < j ( d i j − d i j Y ) 2 ∑ i < j d i j 2 S(Y)=\sqrt{\frac{\sum_{i<j}(d_{ij}-d_{ij}^{Y})^2}{\sum_{i<j}d_{ij}^2}} S(Y)=∑i<jdij2∑i<j(dij−dijY)2
第一种求解过程(梯度下降):
初始化低维嵌入 Y 0 Y^{0} Y0,可以是随机初始化,也可以是启发式(如取PCA的前 m m m个主成分)。
求偏导: ∂ S ( Y ) ∂ y i = 1 S ( Y ) ⋅ ∑ i < j d i j 2 ∑ j ≠ i ( d i j − d i j Y ) y i − y j d i j Y \frac{\partial S(Y)}{\partial \mathbf{y}_i} = \frac{1}{S(Y) \cdot \sum_{i < j} d_{ij}^2} \sum_{j \neq i} \left(d_{ij} - d_{ij}^Y\right)\frac{\mathbf{y}_i - \mathbf{y}_j}{d_{ij}^Y} ∂yi∂S(Y)=S(Y)⋅∑i<jdij21∑j=i(dij−dijY)dijYyi−yj
梯度下降更新: y i ( t + 1 ) = y i ( t ) − η ∂ S ( Y ) ∂ y i \mathbf{y}_i^{(t+1)} = \mathbf{y}_i^{(t)} - \eta \frac{\partial S(Y)}{\partial \mathbf{y}_i} yi(t+1)=yi(t)−η∂yi∂S(Y),其中 η \eta η为学习率, t t t为迭代次数。
第二种求解过程(特征值分解):
计算中心化的内积矩阵 B B B: b i j = − 1 2 ( d i j 2 − d i ⋅ 2 − d ⋅ j 2 + d ⋅ ⋅ 2 ) b_{ij} = -\frac{1}{2} \left( d_{ij}^2 - d_{i\cdot}^2 - d_{\cdot j}^2 + d_{\cdot\cdot}^2 \right) bij=−21(dij2−di⋅2−d⋅j2+d⋅⋅2)
对 B B B进行特征值分解: B = V Λ V T B=VΛV^{T} B=VΛVT,其中 Λ = d i a g ( λ 1 , λ 2 , … , λ n ) Λ=diag(λ_1,λ_2,…,λ_n) Λ=diag(λ1,λ2,…,λn)是特征值矩阵, V = [ v 1 , v 2 , . . . v n ] V=[v_{1},v_{2},...v_{n}] V=[v1,v2,...vn]为特征向量矩阵。
构造低维表示:选择前 m m m个最大的正特征值 λ 1 , … , λ m \lambda_1,…,\lambda_m λ1,…,λm,计算低维嵌入 Y = V m Λ m 1 / 2 Y=V_{m}Λ_{m}^{1/2} Y=VmΛm1/2
代码实现
scikit-learn提供现成的模块:
from sklearn.manifold import Isomap
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()
# 设置 参数
n_neighbors = 10 # 每个点的邻居数量
n_components = 2 # 降维后的目标维度
# 创建 Isomap 模型
isomap = Isomap(n_neighbors=n_neighbors, n_components=n_components)
# 降维
X_isomap = isomap.fit_transform(X)
# 可视化降维后的结果
plt.figure(figsize=(8, 6))
plt.scatter(X_isomap[:, 0], X_isomap[:, 1], c=color, cmap=plt.cm.Spectral)
plt.title("2D Embedding using Isomap")
plt.xlabel("Component 1")
plt.ylabel("Component 2")
plt.show()