-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMMP.m
166 lines (136 loc) · 4.43 KB
/
MMP.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
function [eigvector, eigvalue] = MMP(gnd,feaLabel,feaUnlabel,options)
% MMP: Maximum Margin Projection
% Semi-supervised version of LSDA (Locality Sensitive Discriminant Analysis)
%
% [eigvector, eigvalue] = MMP(gnd,feaLabel,feaUnlabel,options)
%
% Input:
% gnd - Label vector.
%
% feaLabel - Labeled data matrix. Each row vector of fea is a
% data point.
% feaUnlabel - Unlabeled data matrix. Each row vector of fea is
% a data point.
%
% options - Struct value in Matlab. The fields in options
% that can be set:
%
% WOptions Please see ConstructW.m for detailed options.
%
% beta [0,1] Paramter to tune the weight between
% within-class graph and between-class
% graph. Default 0.1.
% beta*L_b+(1-beta)*W_w
%
% 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.
%
%
%
%
% See also LPP, LGE, LSDA
%
%Reference:
%
% Xiaofei He, Deng Cai and Jiawei Han, "Learning a Maximum Margin
% Subspace for Image Retrieval", IEEE Transactions on Knowledge and Data
% Engineering, vol. 20, no. 2, pp. 189-201, February, 2008.
%
% version 2.1 --July/2007
% version 1.0 --May/2006
%
% Written by Deng Cai (dengcai AT gmail.com)
[nSmpLabel, nFea] = size(feaLabel);
[nSmpUnlabel, nFea2] = size(feaUnlabel);
nSmp = nSmpLabel+nSmpUnlabel;
if nFea ~= nFea2
error('Fea error!');
end
data = [feaLabel;feaUnlabel];
Ww = constructW(data,options.WOptions);
Wb = Ww(1:nSmpLabel,1:nSmpLabel);
[i_idx,j_idx,v_idx] = find(Wb);
for i=1:length(i_idx)
if (gnd(i_idx(i)) == gnd(j_idx(i)))
v_idx(i) = 0;
end
end
Wb = sparse(i_idx,j_idx,v_idx,nSmp,nSmp);
if isfield(options.WOptions,'bSemiSupervised') && options.WOptions.bSemiSupervised
if ~isfield(options.WOptions,'SameCategoryWeight')
options.WOptions.SameCategoryWeight = 1;
end
G2 = zeros(nSmpLabel,nSmpLabel);
Label = unique(gnd);
nLabel = length(Label);
for idx=1:nLabel
classIdx = find(gnd==Label(idx));
G2(classIdx,classIdx) = options.WOptions.SameCategoryWeight;
end
Ww(1:nSmpLabel,1:nSmpLabel) = G2;
end
Db = full(sum(Wb,2));
Wb = -Wb;
for i=1:size(Wb,1)
Wb(i,i) = Wb(i,i) + Db(i);
end
D = full(sum(Ww,2));
if isfield(options,'Regu') && options.Regu
options.ReguAlpha = options.ReguAlpha*sum(D)/length(D);
end
beta = 0.1;
if isfield(options,'beta') && (options.beta > 0) && (options.beta < 1)
beta = options.beta;
end
W = sparse((beta/(1-beta))*Wb+Ww);
clear Wb Ww
%==========================
% If data is too large, the following centering codes can be commented
%==========================
if isfield(options,'keepMean') && options.keepMean
elseif isfield(options,'weightMean') && options.keepMean
if issparse(data)
data = full(data);
end
sampleMean = sum(repmat(D,1,nFea).*data,1)./sum(D);
data = (data - repmat(sampleMean,nSmp,1));
else
if issparse(data)
data = full(data);
end
sampleMean = mean(data,1);
data = (data - repmat(sampleMean,nSmp,1));
end
%==========================
if (~isfield(options,'Regu') || ~options.Regu)
DToPowerHalf = D.^.5;
D_mhalf = DToPowerHalf.^-1;
if nSmp < 5000
tmpD_mhalf = repmat(D_mhalf,1,nSmp);
W = (tmpD_mhalf.*W).*tmpD_mhalf';
clear tmpD_mhalf;
else
[i_idx,j_idx,v_idx] = find(W);
v1_idx = zeros(size(v_idx));
for i=1:length(v_idx)
v1_idx(i) = v_idx(i)*D_mhalf(i_idx(i))*D_mhalf(j_idx(i));
end
W = sparse(i_idx,j_idx,v1_idx);
clear i_idx j_idx v_idx v1_idx
end
W = max(W,W');
data = repmat(DToPowerHalf,1,nFea).*data;
[eigvector, eigvalue] = LGE(W, [], options, data);
else
D = sparse(1:nSmp,1:nSmp,D,nSmp,nSmp);
[eigvector, eigvalue] = LGE(W, D, options, data);
end
eigIdx = find(eigvalue < 1e-10);
eigvalue (eigIdx) = [];
eigvector(:,eigIdx) = [];