数据降维之局部线性嵌入(LLE)

LLE(局部线性嵌入)数据降维

原理解释

当数据具备某些非线性结构,如流形结构时,我们希望降维后的数据仍然保持这些结构。那么就提出了LLE降维算法。
LLE (Locally linear embedding):在数据降维后仍然保留原始高维数据的拓扑结构,这种拓扑结构表现为数据点的局部邻接关系。

此算法我们首先要寻求每个数据点的k个最近邻,然后将当前数据点用k个最近邻线性表出,那么就有相对的权重系数。
我们希望数据在降维后数据点之间依然能保持这种线性表出的关系,并且在满足另外一些约束条件的前提下,我们很容易求得降维后的数据。
具体原理和公式网络上有很多人整理得很好,这里不提了。

LLE算法流程

下面时LLE算法的算法流程,输入为矩阵p*N矩阵X,输出为d*N矩阵Y。矩阵的每一列都表示一个对象,每一行都表示对象的一个特征表示。
这里写图片描述

源代码

%%
%编写程序,实现PCALEE算法
%对图像进行降维实验,并显示降维重建后的图像
%运行已有程序,和自己的对比
%实验报告(伪代码(或流程图)、源代码、实验结果及分析)

%% 预处理和数据输入
clc
clear
addpath(genpath(pwd));%将子孙文件添加到工作目录
load face_images; %导入数据
data = images;
%data = data(:,1:50);
%% 初始化参数
d = 2;
len = 64;
wid = 64;
k = 12;
%%
[p ,N] = size(data);%特征维度和对象数目
[IDX,~] = knnsearch(data',data','K',k+1);
IDX = IDX(:,2:end);
W = zeros(N);
for i = 1:N
    xk = data(:,i);
    index = IDX(i,:);
    Qk_temp = repmat(xk,1,k) - data(:,index);
    Qk = Qk_temp'*Qk_temp;
    wk_temp = Qk\ones(k,1);
    wk = wk_temp/sum(wk_temp);
    W(i,index) = wk;
end
W = W';
I = eye(N);
M = (I-W)*(I-W)';
[P,L] = eigs(M,d+1,0);
P = P(:,2:end);
Y = (P*sqrt(N))';

实验结果与分析

实验结果

选取了409×698的图像数据集进行了测试,选取降维后维数为2,选取最近邻个数 k = 12 ,实验后的部分结果如下:

实验结果分析

我们使用别人制作的降维工具箱“drtoolbox”重新进行计算并和我的程序结果进行比较。工具箱的使用代码和结果如下:

%% 使用工具箱进行进行降维来和我的实验结果进行比较
clc
clear
close all

method = 'LLE';%可选LLE或者PCA
addpath(genpath(pwd));

% 产生测试数据
%[X, labels] = generate_data('helix', 2000);
if strcmp(method,'PCA')
    load AR %导入数据
    [p,N] = size(AR);
    X = double(AR);%导入数据
else
    load face_images %导入数据
    [p,N] = size(images);
    X = double(images);%导入数据
end


% 估计本质维数
%no_dims = round(intrinsic_dim(X, 'MLE'));
%disp(['MLE estimate of intrinsic dimensionality: ' num2str(no_dims)]);
d = 2;
k = 12;
% PCA降维或LLE降维
[mappedX, mapping] = compute_mapping(X', method,d);
Y = mappedX';

if strcmp(method,'PCA')
    x0 = (mapping.mean)';
    W = (mapping.M);
    AR_shift = X - repmat(x0,1,N);

    %%
    close all;
    k = 1;
    y = Y(:,k);
    X_rebuid = W*y + x0;%第k个图像的重建还原

    image = AR(:,k);
    image = reshape(image,50,40);
    imshow(mat2gray(image));%对原矩阵归一化

    figure;
    image_re = X_rebuid;
    image_re = reshape(image_re,50,40);
    imshow(mat2gray(image_re));%对原矩阵归一化

end

降维后的部分数据截图如下:

为了比较性能,找个一个别人写的LEE算法,算是网络版本,代码如下:

% LLE ALGORITHM (using K nearest neighbors)
% [Y] = lle(X,K,dmax)
% X    :data as D x N matrix (D = dimensionality, N = #points)
% K    :number of neighbors
% dmax :max embedding dimensionality
% Y    :embedding as dmax x N matrix
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%function [Y] = lle(X,K,d)
addpath(genpath(pwd));%将子孙文件添加到工作目录
load face_images; %导入数据
data = images;
X = data;
K = 12;
d = 2;
%%
[D,N] = size(X);
fprintf(1,'LLE running on %d points in %d dimensions\n',N,D);

%% Step1: compute pairwise distances & find neighbour
fprintf(1,'-->Finding %d nearest neighbours.\n',K);

X2 = sum(X.^2,1);
distance = repmat(X2,N,1)+repmat(X2',1,N)-2*X'*X;
[sorted,index] = sort(distance);
neighborhood = index(2:(1+K),:);

% Step2: solve for recinstruction weights
fprintf(1,'-->Solving for reconstruction weights.\n');
if(K>D)
  fprintf(1,'   [note: K>D; regularization will be used]\n');
  tol=1e-3; % regularlizer in case constrained fits are ill conditioned
else
  tol=0;
end

W = zeros(K,N);
for ii=1:N
   z = X(:,neighborhood(:,ii))-repmat(X(:,ii),1,K); % shift ith pt to origin
   C = z'*z;                                        % local covariance
   C = C + eye(K,K)*tol*trace(C);                   % regularlization (K>D)
   W(:,ii) = C\ones(K,1);                           % solve Cw=1
   W(:,ii) = W(:,ii)/sum(W(:,ii));                  % enforce sum(w)=1
end;

% Step 3: compute embedding from eigenvects of cost matrix M=(I-W)'(I-W)
fprintf(1,'-->Computing embedding.\n');
% M=eye(N,N); % use a sparse matrix with storage for 4KN nonzero elements
M = sparse(1:N,1:N,ones(1,N),N,N,4*K*N);
for ii=1:N
   w = W(:,ii);
   jj = neighborhood(:,ii);
   M(ii,jj) = M(ii,jj) - w';
   M(jj,ii) = M(jj,ii) - w;
   M(jj,jj) = M(jj,jj) + w*w';
end;

% calculation of embedding
options.disp = 0;
options.isreal = 1;
options.issym = 1;
[Y,eigenvals] = eigs(M,d+1,0,options);
Y = Y(:,2:d+1)'*sqrt(N); % bottom evect is [1,1,1,1...] with eval 0
fprintf(1,'Done.\n');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% other possible regularizers for K>D
%   C = C + tol*diag(diag(C));                       % regularlization
%   C = C + eye(K,K)*tol*trace(C)*K;                 % regularlization  

“网络版”的数据结果和我的版本的结果是一样的。我们开启Matlab的探查功能来比较耗时,结果如下:

猜你喜欢

转载自blog.csdn.net/lusongno1/article/details/79683464