任务描述
本关任务:使用 Python 实现 LLE 算法,并对数据进行降维。
相关知识
为了完成本关任务,你需要掌握:1. LLE 算法思想,2. LLE 算法推导,3. LLE 算法流程。
数据集介绍
本关卡使用数据集为自己制造的流形数据,一共 363 个样本,每个样本有 3 个特征。数据生成代码如下:
from sklearn.utils import check_random_state
n_samples = 500
random_state = check_random_state(0)
p = random_state.rand(n_samples) * (2 * np.pi - 0.55)
t = random_state.rand(n_samples) * np.pi
indices = ((t < (np.pi - (np.pi / 8))) & (t > ((np.pi / 8))))
x, y, z = np.sin(t[indices]) * np.cos(p[indices]), np.sin(t[indices]) * np.sin(p[indices]), np.cos(t[indices])
data = np.array([x, y, z]).T
LLE算法流程
对每个样本确定其邻域。
求得矩阵C及其逆。
求得权重的值,对不属于邻域内的权重令其等于0。
求得M。
对M进行特征分解。
求得M第2小到第d+1小的特征值对应的特征向量。
求得Z。
编程要求
根据提示,在右侧编辑器的 begin-end 间补充代码,使用 python 实现 LLE 算法。
测试说明
程序会调用你实现的方法对数据进行降维,若降维后数据与正确数据 l1 距离均值小于 1 则视为通关,否则输出你降维后的数据。
主要函数代码如下:
def lle(data,d,k):
from scipy.spatial.distance import pdist, squareform
'''
input:data(ndarray):待降维数据,行数为样本个数,列数为特征数
d(int):降维后数据维数
k(int):最近的k个样本
output:Z(ndarray):降维后的数据
'''
#********* Begin *********#
def get_k_maxtria(D, k):
dist = pdist(D, 'euclidean')
dist = squareform(dist)
m = dist.shape[0]
k_idx = np.zeros([m, k])
for i in range(m):
topk = np.argsort(dist[i])[1:k + 1]
k_idx[i] = k_idx[i] + topk
return k_idx.astype(np.int32)
def get_w(D, knear_idx, k):
m = D.shape[0]
w = np.zeros([m, k])
I = np.ones((k, 1))
for i in range(m):
Q_x = D[knear_idx[i]]
xi = D[i]
xi = np.tile(xi, (k,1))
C = np.dot((xi - Q_x), (xi-Q_x).T)
C = C +np.eye(k)*(1e-3)*np.trace(C)
C_inv = np.linalg.pinv(C)
w[i,:] = np.sum(C_inv, axis=0)/np.sum(C_inv)
return w
m = data.shape[0]
knear_idx = get_k_maxtria(data, k)
w = get_w(data, knear_idx, k)
W = np.zeros([m,m])
for i in range(m):
for j in range(k):
idx = knear_idx[i, j]
W[i, idx] = w[i, j]
I = np.eye(m)
M = np.dot((I-W).T, (I-W))
A, U = np.linalg.eig(M)
top_A_idx = np.argsort(A)[1:d+1]
Z = U[:,top_A_idx]
return Z
任务描述
本关任务:使用sklearn
实现LLE
算法,并对数据进行降维。
相关知识
为了完成本关任务,你需要掌握:1. LocallyLinearEmbedding 。
LocallyLinearEmbedding
在降维时,LocallyLinearEmbedding 的构造函数中有两个常用的参数可以设置:
-
n_components :即我们进行 LLE 降维时降到的维数。在降维时需要输入这个参数;
-
n_neighbors : 样本邻域内样本个数。
LocallyLinearEmbedding 类中的 fit_transform 函数用于训练模型并进行降维,返回降维后的数据, fit_transform 函数有一个向量输入:
- X :大小为**[样本数量,特征数量]**的 ndarray ,存放需降维的样本。
LocallyLinearEmbedding 的使用代码如下:
from sklearn.manifold import LocallyLinearEmbedding
lle = LocallyLinearEmbedding()
Z = lle.fit_transform(X)
编程要求
根据提示,在右侧编辑器的 begin-end 之间补充代码,实现 LLE 算法。
主要函数代码如下:
from sklearn.manifold import LocallyLinearEmbedding
def lle(data,d,k):
'''
input:data(ndarray):待降维数据
d(int):降维后数据维度
k(int):邻域内样本数
output:Z(ndarray):降维后数据
'''
#********* Begin *********#
lle = LocallyLinearEmbedding(n_components=d, n_neighbors=k, random_state=0)
Z = lle.fit_transform(data)
#********* End *********#
return Z