文章目录
- 等度量映射(仅保留点与其邻近点的距离)
- 算法介绍
- 实验分析
- 局部线性嵌入(不仅保留点与其邻近点的距离还要保留邻近关系)
- 算法介绍
- 实验分析
等度量映射(仅保留点与其邻近点的距离)
算法介绍
等度量映射(Isomap)的基本思想是通过保持数据点之间的测地距离(沿着数据流形的最短路径测量的距离)来近似保持数据流形的局部几何结构。这与传统的多维缩放(MDS)不同,MDS通常保持点之间的欧几里德距离,而这可能在流形结构下失效。
而流形是指在高维空间中嵌入的低维结构,这种结构可能是非线性的、弯曲的,而不是简单的线性关系。
接着利用流行在局部上与欧式空间同胚这个性质,对每个点基于欧式距离找出其近邻点,然后将近邻点连接起来,构成一个无向图,接着使用Dijkstra或Floyd求解最短路径构成距离矩阵,最终使用MDS算法求解。
其中同胚是指,一个 n n n维流形是指每个点都有一个邻域,该邻域与 n n n维欧式空间中的开集同胚。这意味着在每个点的附近,流形的局部结构可以用欧式空间的坐标系统来描述。虽然整个流形可能是非欧式的,但在每个点处,我们可以找到一个局部的坐标系统,使得该点附近的结构与欧式空间中的结构相似。(这与微积分的定义很相似,都是在某一邻域上的近似)
下图是Isomap的算法流程图:
Isomap 只提供了训练样本在低维空间的坐标,对于新样本,一种通用的方法是使用回归学习器。通过将训练样本的高维空间坐标作为输入,相应的低维空间坐标作为输出,训练一个回归模型。该模型可用于对新样本的低维空间坐标进行预测,尽管这只是一种权宜之计,目前似乎还没有更好的方法来处理 Isomap 在新样本上的映射问题。
构建近邻图有两种常见方法:一是指定K近邻点,二是指定距离阈值得到d近邻图。但两者存在问题,过大的近邻范围可能导致“短路”,将远距离点误认为近邻;反之,过小的范围可能导致“断路”,某些区域与其他区域失去连接。这可能对后续最短路径计算产生误导。选择构建方法时需要权衡参数以避免这些问题。
实验分析
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# 读取数据
data = pd.read_csv('data/correlated_dataset.csv')# 计算欧氏距离
def euclidean_distance(point1, point2):return np.sqrt(np.sum((point1 - point2)**2))# 计算近邻图
def compute_neighbors(data, k=5):num_samples = len(data)neighbors = np.zeros((num_samples, k), dtype=int)for i in range(num_samples):distances = [euclidean_distance(data.iloc[i], data.iloc[j]) for j in range(num_samples) if i != j]indices = np.argsort(distances)[:k]neighbors[i] = indicesreturn neighbors# 计算测地距离
def compute_geodesic_distances(neighbors, data):num_samples = len(data)geodesic_distances = np.zeros((num_samples, num_samples))for i in range(num_samples):for j in range(num_samples):if i != j:path_distance = 0current = inext_neighbor = neighbors[i, 0]while next_neighbor != j:path_distance += euclidean_distance(data.iloc[current], data.iloc[next_neighbor])current = next_neighbornext_neighbor = neighbors[current, 0]geodesic_distances[i, j] = path_distancereturn geodesic_distances# Isomap算法
def isomap(data, k_neighbors=5, low_dim=2):# 计算近邻图neighbors = compute_neighbors(data, k_neighbors)# 计算测地距离geodesic_distances = compute_geodesic_distances(neighbors, data)# 使用MDS算法降维n = len(data)H = np.eye(n) - np.ones((n, n)) / nB = -0.5 * H @ geodesic_distances**2 @ Heigvals, eigvecs = np.linalg.eigh(B)# 取最小的low_dim个特征值对应的特征向量indices = np.argsort(eigvals)[:low_dim]low_dim_eigvecs = eigvecs[:, indices]return low_dim_eigvecs# 降维
low_dim_data = isomap(data.drop(columns=['Target']))# 可视化降维结果
plt.scatter(low_dim_data[:, 0], low_dim_data[:, 1], c=data['Target'], cmap='viridis')
plt.title('Isomap降维结果')
plt.xlabel('主成分1')
plt.ylabel('主成分2')
plt.show()
局部线性嵌入(不仅保留点与其邻近点的距离还要保留邻近关系)
算法介绍
与Isomap算法不同,局部线性嵌入(LLE)算法是要保留邻近关系。
如下图所示:
假定样本点 x i x_i xi的坐标能通过它的领域内的样本 x j , x k , x l x_j,x_k,x_l xj,xk,xl的坐标通过线性组合而重构出来的,即:
x i = w i j x j + w i k x k + w i l x l (1) x_i=w_{ij}x_j+w_{ik}x_k+w_{il}x_l\tag{1} xi=wijxj+wikxk+wilxl(1)
而LLE算法希望式(1)这种关系能在低维空间中依然存在。
LLE算法先对每个样本 x i x_i xi找出其近邻的下标集合 Q i Q_i Qi,然后计算出基于 Q i Q_i Qi中的样本点对 x i x_i xi进行线性重构的系数 w i w_i wi:
min w 1 , w 2 , … , w m ∑ i = 1 m ∥ x i − ∑ j ∈ Q i w i j x j ∥ 2 2 s.t. ∑ j ∈ Q i w i j = 1 (2) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m\left\|\boldsymbol{x}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 \\ \text { s.t. } & \sum_{j \in Q_i} w_{i j}=1 \end{aligned} \tag{2} w1,w2,…,wmmin s.t. i=1∑m xi−j∈Qi∑wijxj 22j∈Qi∑wij=1(2)
我们可以将式(2)进行恒等变形:
∑ i = 1 m ∥ x i − ∑ j ∈ Q i w i j x j ∥ 2 2 = ∑ i = 1 m ∥ ∑ j ∈ Q i w i j x i − ∑ j ∈ Q i w i j x j ∥ 2 2 = ∑ i = 1 m ∥ ∑ j ∈ Q i w i j ( x i − x j ) ∥ 2 2 = ∑ i = 1 m ∥ X i w i ∥ 2 2 = ∑ i = 1 m w i T X i T X i w i (3) \begin{aligned} \sum_{i=1}^m\left\|\boldsymbol{x_i}-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 & =\sum_{i=1}^m\left\|\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{x}_j\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\sum_{j \in Q_i} w_{i j}\left(\boldsymbol{x}_i-\boldsymbol{x}_j\right)\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}}\right\|_2^2 \\ & =\sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}{ }^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}} \end{aligned} \tag{3} i=1∑m xi−j∈Qi∑wijxj 22=i=1∑m j∈Qi∑wijxi−j∈Qi∑wijxj 22=i=1∑m j∈Qi∑wij(xi−xj) 22=i=1∑m∥Xiwi∥22=i=1∑mwiTXiTXiwi(3)
其中 w i = ( w i q i 1 , w i q i 2 , … , w i q i n ) ∈ R n × 1 , X i = ( x i − x q i 1 , x i − x q i 2 , … , x i − x q i n ) ∈ R d × n \boldsymbol{w}_{\boldsymbol{i}}=\left(w_{i q_i^1}, w_{i q_i^2}, \ldots, w_{i q_i^n}\right) \in \mathbb{R}^{n \times 1}, \mathbf{X}_i=\left(\boldsymbol{x}_i-\boldsymbol{x}_{q_i^1}, \boldsymbol{x}_i-\boldsymbol{x}_{q_i^2}, \ldots, \boldsymbol{x}_i-\boldsymbol{x}_{q_i^n}\right) \in \mathbb{R}^{d \times n} wi=(wiqi1,wiqi2,…,wiqin)∈Rn×1,Xi=(xi−xqi1,xi−xqi2,…,xi−xqin)∈Rd×n。约束条件可进行如下恒等变形:
∑ j ∈ Q i w i j = w i T E = 1 (4) \sum_{j\in Q_i}w_{ij}=w_i^T\mathbf{E}=1\tag{4} j∈Qi∑wij=wiTE=1(4)
其中 E = ( 1 , 1 , . . . , 1 ) ∈ R n × 1 \mathbf{E}=(1,1,...,1)\in \mathbb{R}^{n\times 1} E=(1,1,...,1)∈Rn×1为 n n n行1列的单位向量。
故优化问题可重写成:
min w 1 , w 2 , … , w m ∑ i = 1 m w i T X i T X i w i s.t. w i T E = 1 (5) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}{ }^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}} \\ \text { s.t. } & w_i^T\mathbf{E}=1 \end{aligned} \tag{5} w1,w2,…,wmmin s.t. i=1∑mwiTXiTXiwiwiTE=1(5)
采用拉格朗日乘子法求解,有:
L ( w 1 , w 2 , … , w m , λ ) = ∑ i = 1 m w i T X i T X i w i + λ ( w i T E − 1 ) (6) L\left(\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m, \lambda\right)=\sum_{i=1}^m \boldsymbol{w}_{\boldsymbol{i}}^{\mathrm{T}} \mathbf{X}_i^{\mathrm{T}} \mathbf{X}_i \boldsymbol{w}_{\boldsymbol{i}}+\lambda\left(\boldsymbol{w}_{\boldsymbol{i}}^{\mathrm{T}} \boldsymbol{E}-1\right)\tag{6} L(w1,w2,…,wm,λ)=i=1∑mwiTXiTXiwi+λ(wiTE−1)(6)
式(6)对 w i w_i wi求偏导并令其为零,有:
∂ L ∂ w i = 2 X i T X i w i + λ E = 0 (8) \frac{\partial L}{\partial w_i}=2 \mathbf{X}_i^T \mathbf{X}_i w_i+\lambda \boldsymbol{E}=0 \tag{8} ∂wi∂L=2XiTXiwi+λE=0(8)
则:
w i = − 1 2 λ ( X i T X i ) − 1 E (9) w_i=-\frac{1}{2}\lambda (\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}\tag{9} wi=−21λ(XiTXi)−1E(9)
又因为 w i T E = E T w i = 1 w_i^T\mathbf{E}=\mathbf{E}^Tw_i=1 wiTE=ETwi=1,故式(9)两边同时左乘 E T \mathbf{E}^T ET,有:
E T w i = − 1 2 λ E T ( X i T X i ) − 1 E − 1 2 λ = 1 E T ( X i T X i ) − 1 E (10) \begin{aligned} \boldsymbol{E}^Tw_i&=-\frac{1}{2}\lambda \boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}\\ -\frac{1}{2}\lambda&=\frac{1}{\boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}} \end{aligned}\tag{10} ETwi−21λ=−21λET(XiTXi)−1E=ET(XiTXi)−1E1(10)
然后回代入式(9)中,有:
w i = ( X i T X i ) − 1 E E T ( X i T X i ) − 1 E (11) w_i=\frac{(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}}{\boldsymbol{E}^T(\mathbf{X}_i^T\mathbf{X}_i)^{-1}\boldsymbol{E}}\tag{11} wi=ET(XiTXi)−1E(XiTXi)−1E(11)
令矩阵 ( X i T X i ) − 1 (\mathbf{X}_i^T\mathbf{X}_i)^{-1} (XiTXi)−1第 i i i行第 k k k列的元素为 C j k − 1 C_{jk}^{-1} Cjk−1,即 C j k = ( x i − x j ) T ( x i − x j ) C_{jk}=(x_i-x_j)^T(x_i-x_j) Cjk=(xi−xj)T(xi−xj),则:
w i j = w i q i j = ∑ k ∈ Q i C j k − 1 ∑ l , s ∈ Q i C l s − 1 (12) w_{i j}=w_{i q_i^j}=\frac{\sum_{k \in Q_i} C_{j k}^{-1}}{\sum_{l, s \in Q_i} C_{l s}^{-1}} \tag{12} wij=wiqij=∑l,s∈QiCls−1∑k∈QiCjk−1(12)
其中 w i j w_{ij} wij原始数据集中的某个数据点 x i \boldsymbol{x}_i xi的邻近集合 Q i Q_i Qi中的某个邻居点 x j \boldsymbol{x}_j xj对重构 x i \boldsymbol{x}_i xi的权重。
由于LLE在低维空间中保持 w i w_i wi不变,于是 x i x_i xi对应的低维空间坐标 z i z_i zi可通过下式求解:
min w 1 , w 2 , … , w m ∑ i = 1 m ∥ z i − ∑ j ∈ Q i w i j z j ∥ 2 2 (13) \begin{aligned} \min _{\boldsymbol{w}_1, \boldsymbol{w}_2, \ldots, \boldsymbol{w}_m} & \sum_{i=1}^m\left\|\boldsymbol{z}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{z}_j\right\|_2^2 \\ \end{aligned} \tag{13} w1,w2,…,wmmini=1∑m zi−j∈Qi∑wijzj 22(13)
令 Z = ( z 1 , z 2 , … , z m ) ∈ R d ′ × m , ( W ) i j = w i j \mathbf{Z}=\left(\boldsymbol{z}_1, \boldsymbol{z}_2, \ldots, \boldsymbol{z}_m\right) \in \mathbb{R}^{d^{\prime} \times m},(\mathbf{W})_{i j}=w_{i j} Z=(z1,z2,…,zm)∈Rd′×m,(W)ij=wij。
M = ( E − W ) T ( E − W ) (14) \mathbf{M}=\mathbf{(E-W)^T(E-W)}\tag{14} M=(E−W)T(E−W)(14)
故式(13)可重写为:
min Z ∑ i = 1 m ∥ z i − ∑ j ∈ Q i w i j z j ∥ 2 2 = ∑ i = 1 m ∥ Z E i − Z W i ∥ 2 2 = ∑ i = 1 m ∥ Z ( E i − W i ) ∥ 2 2 = ∑ i = 1 m ( Z ( E i − W i ) ) T Z ( E i − W i ) = ∑ i = 1 m ( E i − W i ) T Z T Z ( E i − W i ) = tr ( ( E − W ) T Z T Z ( E − W ) ) = tr ( Z ( E − W ) ( E − W ) T Z T ) = tr ( Z M Z T ) (15) \begin{aligned} \min _{\boldsymbol{Z}} \sum_{i=1}^m\left\|\boldsymbol{z}_i-\sum_{j \in Q_i} w_{i j} \boldsymbol{z}_j\right\|_2^2 & =\sum_{i=1}^m\left\|\boldsymbol{Z} \boldsymbol{E}_i-\boldsymbol{Z} \boldsymbol{W}_i\right\|_2^2 \\ & =\sum_{i=1}^m\left\|\boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)\right\|_2^2 \\ & =\sum_{i=1}^m\left(\boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)\right)^T \boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right) \\ & =\sum_{i=1}^m\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right)^T \boldsymbol{Z}^T \boldsymbol{Z}\left(\boldsymbol{E}_i-\boldsymbol{W}_i\right) \\ & =\operatorname{tr}\left((\boldsymbol{E}-\boldsymbol{W})^T \boldsymbol{Z}^T \boldsymbol{Z}(\boldsymbol{E}-\boldsymbol{W})\right) \\ & =\operatorname{tr}\left(\boldsymbol{Z}(\boldsymbol{E}-\boldsymbol{W})(\boldsymbol{E}-\boldsymbol{W})^T \boldsymbol{Z}^T\right) \\ & =\operatorname{tr}\left(\boldsymbol{Z} \boldsymbol{M} \boldsymbol{Z}^T\right)\\ \end{aligned}\tag{15} Zmini=1∑m zi−j∈Qi∑wijzj 22=i=1∑m∥ZEi−ZWi∥22=i=1∑m∥Z(Ei−Wi)∥22=i=1∑m(Z(Ei−Wi))TZ(Ei−Wi)=i=1∑m(Ei−Wi)TZTZ(Ei−Wi)=tr((E−W)TZTZ(E−W))=tr(Z(E−W)(E−W)TZT)=tr(ZMZT)(15)
其约束条件为 Z T Z = E \mathbf{Z^TZ=E} ZTZ=E是为了得到标准化的低维数据。
整理一下可得:
min Z tr ( Z M Z T ) s.t. Z T Z = E (16) \begin{aligned} \min _{\mathbf{Z}} & \operatorname{tr}\left(\boldsymbol{Z} \boldsymbol{M} \boldsymbol{Z}^T\right) \\ \text { s.t. } & \mathbf{Z^TZ=E} \end{aligned} \tag{16} Zmin s.t. tr(ZMZT)ZTZ=E(16)
最终可通过对 M \mathbf{M} M进行特征值分解,取 M \mathbf{M} M最小的 d ′ d^\prime d′个特征值所对应的特征向量组成的矩阵即为 Z T \mathbf{Z^T} ZT。
LLE算法流程图如下所示:
实验分析
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# 读取数据
data = pd.read_csv('data/correlated_dataset.csv')# LLE算法实现
def lle(X, n_neighbors, n_components):m, d = X.shapeW = np.zeros((m, m))# Step 1: 选择近邻for i in range(m):indices = find_neighbors(X[i], X, n_neighbors)W[i, indices] = compute_weights(X[i], X[indices], indices)# Step 2: 计算低维表示M = np.identity(m) - Weigenvalues, eigenvectors = np.linalg.eigh(M)idx = np.argsort(eigenvalues)[1:n_components + 1]embedding = eigenvectors[:, idx]return embedding# 找到近邻
def find_neighbors(x, X, n_neighbors):distances = np.linalg.norm(X - x, axis=1)indices = np.argsort(distances)[:n_neighbors]return indices# 计算权重
def compute_weights(x, X, indices):Z = X - xC = Z @ Z.Tones = np.ones(len(indices))w = np.linalg.solve(C + 1e-3 * np.identity(len(indices)), ones)w /= np.sum(w)return w# 降维并可视化
embedding = lle(data.values[:, :-1], n_neighbors=10, n_components=2)plt.scatter(embedding[:, 0], embedding[:, 1], c=data['Target'], cmap='viridis')
plt.title('LLE Visualization')
plt.show()