📄 npe.m
字号:
function [eigvector, eigvalue, elapse] = NPE(options, data)
% NPE: Neighborhood Preserving Embedding
%
% [eigvector, eigvalue, elapse] = NPE(options, data)
%
% Input:
% data - Data matrix. Each row vector of data is a data point.
%
% options - Struct value in Matlab. The fields in options
% that can be set:
%
% NeighborMode - Indicates how to construct the graph. Choices
% are:
% 'KNN' - Put an edge between two nodes if and
% only if they are among the k nearst
% neighbors of each other. Default
% option.
% 'Supervised' - Two variations:
% 1. k=0, Put an edge between two nodes
% if and only if they belong to
% same class.
% 2. k>0, The distance between two nodes
% in the same class will be smaller than
% two nodes have diff. labels
% The label information 'gnd' should be
% provided.
%
% k - The number of neighbors.
% Default k = 5;
% gnd - The parameter needed under 'Supervised'
% NeighborMode. Colunm vector of the label
% information for each data point.
%
% Please see LGE.m for other options.
%
%
% Output:
% eigvector - Each column is an embedding function, for a new
% data point (row vector) x, y = x*eigvector
% will be the embedding result of x.
% eigvalue - The eigvalue of LPP eigen-problem. sorted from
% smallest to largest.
% elapse - Time spent on different steps
%
%
% Examples:
%
%
%
% fea = rand(50,70);
% gnd = [ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4];
% options = [];
% options.k = 5;
% options.NeighborMode = 'Supervised';
% options.gnd = gnd;
% [eigvector, eigvalue] = NPE(options, fea);
% Y = fea*eigvector;
%
%
%
% See also LPP, LGE
%
%Reference:
%
% Xiaofei He, Deng Cai, Shuicheng Yan, and Hong-Jiang
% Zhang, "Neighborhood Preserving Embedding", Tenth IEEE International
% Conference on Computer Vision (ICCV'2005), 2005
%
% Sam Roweis & Lawrence Saul. "Nonlinear dimensionality reduction by
% locally linear embedding", Science, v.290 no.5500 , Dec.22, 2000.
% pp.2323--2326.
%
% version 2.1 --June/2007
% version 2.0 --May/2007
% version 1.1 --May/2006
% version 1.0 --Feb/2005
%
% Written by Deng Cai (dengcai2 AT cs.uiuc.edu)
bGlobal = 0;
if ~exist('data','var')
bGlobal = 1;
global data;
end
if (~exist('options','var'))
options = [];
end
if ~isfield(options,'NeighborMode')
options.NeighborMode = 'KNN';
end
if ~isfield(options,'k')
options.k = 5;
end
[nSmp,nFea] = size(data);
if options.k >= nSmp
error('k is too large!');
end
if(options.k > nFea)
tol=1e-3; % regularlizer in case constrained fits are ill conditioned
else
tol=1e-12;
end
tmp_T = cputime;
if options.k <= 0 % Always supervised!
if ~isfield(options,'gnd')
error('gnd should be provided!');
end
if length(options.gnd) ~= nSmp
error('gnd and data mismatch!');
end
if ~isfield(options,'bEigs')
options.bEigs = 0;
end
W = zeros(nSmp,nSmp);
for ii=1:nSmp
idx = find(options.gnd==options.gnd(ii));
idx(find(idx==ii)) = [];
z = data(idx,:)-repmat(data(ii,:),length(idx),1); % shift ith pt to origin
C = z*z'; % local covariance
C = C + eye(size(C))*tol*trace(C); % regularlization
tW = C\ones(length(idx),1); % solve Cw=1
tW = tW/sum(tW); % enforce sum(w)=1
W(idx,ii) = tW;
end
M = (eye(size(W)) - W);
M = M*M';
M = max(M,M');
M = sparse(M);
else
switch lower(options.NeighborMode)
case {lower('KNN')}
Distance = EuDist2(data,[],0);
[sorted,index] = sort(Distance,2);
neighborhood = index(:,2:(1+options.k));
case {lower('Supervised')}
if ~isfield(options,'gnd')
error('gnd should be provided!');
end
if length(options.gnd) ~= nSmp
error('gnd and data mismatch!');
end
if ~isfield(options,'bEigs')
options.bEigs = 0;
end
nLabel = length(Label);
neighborhood = zeros(nSmp,options.k);
for idx=1:nLabel
classIdx = find(options.gnd==Label(idx));
if options.k >= length(classIdx)
error('k is too large!');
end
Distance = EuDist2(data(classIdx,:),[],0);
[sorted,index] = sort(Distance,2);
neighborhood(classIdx,:) = classIdx(index(:,2:(1+options.k)));
end
otherwise
error('NeighborMode does not exist!');
end
W = zeros(options.k,nSmp);
for ii=1:nSmp
z = data(neighborhood(ii,:),:)-repmat(data(ii,:),options.k,1); % shift ith pt to origin
C = z*z'; % local covariance
C = C + eye(size(C))*tol*trace(C); % regularlization
W(:,ii) = C\ones(options.k,1); % solve Cw=1
W(:,ii) = W(:,ii)/sum(W(:,ii)); % enforce sum(w)=1
end
for ii=1:nSmp
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
M = max(M,M');
M = sparse(M);
end
timeW = cputime - tmp_T;
%==========================
% If data is too large, the following centering codes can be commented
%==========================
if isfield(options,'keepMean') & options.keepMean
;
else
if issparse(data)
data = full(data);
end
sampleMean = mean(data);
data = (data - repmat(sampleMean,nSmp,1));
end
%==========================
M = -M;
for i=1:size(M,1)
M(i,i) = M(i,i) + 1;
end
if bGlobal & isfield(options,'keepMean') & options.keepMean
[eigvector, eigvalue, elapse] = LGE(M, [], options);
else
[eigvector, eigvalue, elapse] = LGE(M, [], options, data);
end
elapse.timeW = timeW;
elapse.timeAll = elapse.timeAll + elapse.timeW;
eigIdx = find(eigvalue < 1e-10);
eigvalue (eigIdx) = [];
eigvector(:,eigIdx) = [];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -