简介
流形学习是一类借鉴了拓扑流形概念的降维方法。流形是在局部与欧式空间同胚的空间,换言之,它在局部具有欧式空间的性质,能用欧式距离来进行距离计算。若低维流形嵌入到高维空间中,则数据样本在高维空间的分布虽然看上去非常复杂,但在局部上仍具有欧式空间的性质,基于流形学习的降维正是这种“邻域保持”的思想。如此,可以在局部建立降维映射关系,然后再设法将局部映射推广到全局。当维数被降至二维或三维时,能对数据进行可视化展示。因此流形学习也可被用于可视化 . 本节介绍两种著名的流形学习方法。
局部线性嵌入(LLE)
局部线性嵌入试图保持邻域内样本之间的线性关系.
LLE 希望式子的关系在低维空间中得以保持.
等度量映射ISOMAP
前面的 LLE ,被称作局部模型。因为他们都只关注样本点跟邻居们的关系。现在我们介绍一个全局模型 ISOMAP ( 多维缩放( MDS )的一个变种)。 利用流形在局部上与欧氏空间同胚这个性质,对每个点基于欧氏距离找出其近邻点,然后就能建立一个近邻连接图,图中近邻点之间存在连接,而非近邻点之间不存在连接,于是,计算两点之间测地线距离的问题就转变为计算近邻连接图上两点之间的最短路径问题.
在近邻连接图上计算两点间的最短路径,可采用著名的Dikstra算法或Floyd 算法,在得到任意两点的距离之后,就可通过 MDS 方法来获得样本点在低维空间中的坐标.(两种距离算法和MDS在我的文章中有大家可以看看)
Isomap算法描述
MATLAB实验结果:
LLE算法中近邻点数不同K的选取实验结果图
K分别为5,6,8,10,12,14,16,16,18,20,20时降维的图。
由实验结果可看出,近邻点数目的取值与降维结果紧密联系,当K值过小时,同类数据可能被分开,实验结果出错。
K值过大时数据呈流型结构,当K值取合理时,数据降维达到预期目标。
ISOMAP算法实现
降维前在三维图上的测地距离
用ISOMAP降维后的测地距离
结论
值得注意的是,流形学习欲有效进行邻域保持则需样本密采样,而这恰是高维情形下面临的重大障碍;因此流形学习方法在实践中的降维性能往往没有预期的好 。
流形学习算法也可以按照算法本身关注的结构信息可以分为两类:一类是保持全局的结构信息,比如ISOMAP,使高维空间中任意点对之间的测地距离关系在低维空间中保持不变;另一类是保持局部的结构信息,比如LLE等,这些算法首先是考虑局部邻域信息,局部信息的重叠能够提供全局的信息。
全局算法要求流形必须是凸结构的,只有这样才能保持流形上距离较远的点能够准确降维,由于要找出相距远点的测地距离,所以要花费很多的运算时间,时间复杂度高。局部算法只考虑流形上近邻点之间的关系,保证流形的局部几何结构不变,使流形上近距离的点映射成低维空间中的邻近点,所以不必要求流形必须是凸结构的,局部性质的保持可以在非凸流形上成功应用,适用范围较广。
LLE不需要计算距离矩阵,仅仅需要计算稀疏矩阵,大大减少了计算量。由于是局部优化算法,只考虑距离近的点,这种局部性质的保持可以在非凸流形上成功的应用,因此应用范围比广泛,但是这种局部性质的保持,对于数据稀疏的数据集,近邻区域很有可能不位于一个平面上,基于局部线性嵌入的降维算法研究则误差函数形成的误差比较大,影响降维效果;数据集之间的关联性弱,局部信息的重叠不可能反映整体的全局结构。
LLEmatlab代码主程序:
% 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) [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
clear all,clc K = 16 ;%(领域点个数) d = 2;%最大嵌入维数 %瑞士卷的生成图 N=4000; t=(3*pi/2)*(1+2*rand(1,N)); s=21*rand(1,N); X=[t.*cos(t);s;t.*sin(t)]; plot3(X(1,:),X(2,:),X(3,:),'.') %用lle降维 Y=lle(X,K,d); figure plot(Y(1,:),Y(2,:),'.r')
clc; clear all; close all; %用isomap对瑞士卷降维 %瑞士卷的生成图 N=1000; t=(3*pi/2)*(1+2*rand(1,N)); s=21*rand(1,N); X=[t.*cos(t);s;t.*sin(t)]; %plot3(X(1,:),X(2,:),X(3,:),'.') %计算距离矩阵个 X=X'; [m,n]=size(X); D=zeros(m,m); for i=1:m for j=i:m D(i,j)=norm(X(i,:)-X(j,:)); D(j,i)=D(i,j); end end %计算矩阵中每行前k个值的位置并赋值(先按大小排列) W1=zeros(m,m); k=8; for i=1:m A=D(i,:); t=sort(A(:));%对每行进行排序后构成一个从小到大有序的列向量 [row,col]=find(A<=t(k),k);%找出每行前K个最小数的位置 for j=1:k c=col(1,j); W1(i,c)=D(i,c); %W1(i,c)=1;%给k近邻赋值为距离 end end for i=1:m for j=1:m if W1(i,j)==0&i~=j W1(i,j)=inf; end end end %计算测地距离o就是测地距离 [dist,mypath,o]=myfloyd(W1,10,20); figure [col,rol]=size(mypath); X1=[]; for i=1:rol ding=mypath(1,i); X1=[X1;X(ding,:)]; end plot3(X(:,1),X(:,2),X(:,3),'.') hold on plot3(X1(:,1),X1(:,2),X1(:,3),'o-r') %mds算法降维 d=o; n=size(d,1); B=zeros(n,n); for i=1:n for j=1:n B(i,j)=-0.5*(d(i,j)^2 -1/n*d(i,:)*d(i,:)' -1/n*d(:,j)'*d(:,j) +1/n^2*sum(sum(d.^2))); end end [V,D]=eig(B); A=sort(diag(D),'descend');%把对角矩阵变成列向量 V1=[V(:,1),V(:,2)]*[A(1,1),0;0,A(2,1)]; figure; %plot(V1(:,1),V1(:,2),'.') [col,rol]=size(mypath); V2=[]; for i=1:rol ding=mypath(1,i); V2=[V2;V1(ding,:)]; end plot(V1(:,1),V1(:,2),'.') hold on plot(V2(:,1),V2(:,2),'o-r')