用python实现LLE降维并举例
时间: 2024-06-09 15:07:07 浏览: 170
Locally Linear Embedding (LLE) 是一种非线性降维方法,它能够将高维数据映射到低维空间中,同时保持数据之间的局部线性关系。下面是使用 Python 实现 LLE 的步骤及代码示例:
1. 导入必要的库
```python
import numpy as np
from scipy.spatial.distance import cdist
from sklearn.neighbors import NearestNeighbors
```
2. 定义 LLE 函数
```python
def lle(X, n_components, k=5):
"""
:param X: 数据矩阵,每行表示一个数据点
:param n_components: 降维后的维度
:param k: 用于计算权重矩阵 W 的 k 近邻数
:return: 降维后的数据矩阵 Y
"""
m, d = X.shape # m 表示数据点数量,d 表示每个数据点的维度
# Step 1: 计算权重矩阵 W
nbrs = NearestNeighbors(n_neighbors=k+1, algorithm='ball_tree').fit(X)
distances, indices = nbrs.kneighbors(X)
indices = indices[:, 1:] # 去掉每个点本身
W = np.zeros((m, m))
for i in range(m):
Z = X[indices[i]] - X[i] # 将 X[i] 降到二维,重心为原点
C = np.dot(Z, Z.T)
C += np.eye(k) * 1e-3 * np.trace(C) # 为了数值稳定性,加入一个小的偏置项
W[i, indices[i]] = np.linalg.solve(C, np.ones(k)) / np.sum(np.linalg.solve(C, np.ones(k)))
# Step 2: 计算降维后的数据矩阵 Y
I = np.eye(m)
M = (I - W).T @ (I - W)
eigenvalues, eigenvectors = np.linalg.eig(M)
indices = np.argsort(eigenvalues)[1:n_components+1]
Y = eigenvectors[:, indices].real
return Y
```
3. 生成数据并进行降维
```python
# 生成三维球形数据
theta = np.random.rand(1000) * np.pi
phi = np.random.rand(1000) * 2 * np.pi
x = np.sin(theta) * np.cos(phi)
y = np.sin(theta) * np.sin(phi)
z = np.cos(theta)
X = np.array([x, y, z]).T
# 降维到二维
Y = lle(X, n_components=2)
# 可视化结果
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].scatter(X[:, 0], X[:, 1], s=5)
axs[0].set_title('Original Data')
axs[1].scatter(Y[:, 0], Y[:, 1], s=5)
axs[1].set_title('LLE Embedding')
plt.show()
```
运行结果如下图所示:
![LLE embedding](https://i.imgur.com/Gn8bBjI.png)
从图中可以看出,LLE 方法将三维球状数据成功地降维到了二维平面上,并保持了数据之间的局部线性关系。
阅读全文