1 | function w = incsvc(a,ktype,par,C) |
---|
2 | %INCSVC Incremental support vector classifier |
---|
3 | % |
---|
4 | % W = INCSVC(A,KTYPE,PAR,C) |
---|
5 | % |
---|
6 | % INPUT |
---|
7 | % A Dataset |
---|
8 | % KTYPE Type of the kernel (optional; default: 'p') |
---|
9 | % PAR Kernel parameter (optional; default: 1) |
---|
10 | % C Regularization parameter (optional; default: 1) |
---|
11 | % |
---|
12 | % OUTPUT |
---|
13 | % W Mapping: Support Vector Classifier |
---|
14 | % |
---|
15 | % DESCRIPTION |
---|
16 | % Optimizes a support vector classifier for the dataset A by an |
---|
17 | % incremental procedure to perform the quadratic programming. The |
---|
18 | % classifier can be of one of the types as defined by PROXM. Default is |
---|
19 | % linear (TYPE = 'p', PAR = 1). The kernel computation is done by |
---|
20 | % INCKERNEL which is more lightweight than PROXM. C < 1 allows for |
---|
21 | % more class overlap. Default C = 1. |
---|
22 | % |
---|
23 | % See also ADD_OBJ_CL, SVC, INCKERNEL |
---|
24 | |
---|
25 | % Copyright: D.M.J. Tax, D.M.J.Tax@prtools.org |
---|
26 | % Faculty EWI, Delft University of Technology |
---|
27 | % P.O. Box 5031, 2600 GA Delft, The Netherlands |
---|
28 | |
---|
29 | if nargin < 4 | isempty(C) |
---|
30 | C = 1; |
---|
31 | prwarning(3,'Regularization parameter C set to 1\n'); |
---|
32 | end |
---|
33 | if nargin < 3 | isempty(par) |
---|
34 | par = 1; |
---|
35 | prwarning(3,'Kernel parameter par set to 1\n'); |
---|
36 | end |
---|
37 | if nargin < 2 | isempty(ktype) |
---|
38 | ktype = 'p'; |
---|
39 | prwarning(3,'Polynomial kernel type is used\n'); |
---|
40 | end |
---|
41 | if nargin < 1 | isempty(a) |
---|
42 | w = mapping(mfilename,{ktype,par,C}); |
---|
43 | w = setname(w,'Inc. Support Vector Classifier'); |
---|
44 | return; |
---|
45 | end |
---|
46 | |
---|
47 | if ~isa(ktype,'mapping') %training |
---|
48 | %Basic sizes:: |
---|
49 | [N,k,c] = getsize(a); |
---|
50 | %kernel definition: |
---|
51 | kernel = 'inckernel'; |
---|
52 | kpar.type = ktype; |
---|
53 | kpar.s = par; |
---|
54 | %setting for displaying: (I know you can program it shorter, but this is |
---|
55 | %more clear): |
---|
56 | if N>=1000 |
---|
57 | dodisplay = 1; |
---|
58 | else |
---|
59 | dodisplay = 0; |
---|
60 | end |
---|
61 | |
---|
62 | if c==2 |
---|
63 | % randomize the data: |
---|
64 | %I = randperm(N); a = a(I,:); |
---|
65 | a = unrandomize(a); |
---|
66 | |
---|
67 | % settings for the program: |
---|
68 | global X_incremental; |
---|
69 | X_incremental = +a; |
---|
70 | y = 3 - 2*getnlab(a); |
---|
71 | |
---|
72 | % here we go: |
---|
73 | alf = zeros(N,1); % weights |
---|
74 | grad = []; % the gradient of all seen objects |
---|
75 | setR = []; % 'rest' set |
---|
76 | Kr = []; % kernel matrix of the rest objects(RxS) |
---|
77 | setD = []; |
---|
78 | setS = []; |
---|
79 | setE = []; |
---|
80 | Ke = []; |
---|
81 | Ks = 0; |
---|
82 | b = 0; |
---|
83 | R = inf; |
---|
84 | tol = 1e-8; |
---|
85 | |
---|
86 | % startup: |
---|
87 | for c=1:N |
---|
88 | if dodisplay & mod(c,100)==0 |
---|
89 | fprintf('%d/%d ',c,N); |
---|
90 | end |
---|
91 | dd_message(6,'ADD obj %d\n',c); |
---|
92 | add_obj_cl; |
---|
93 | %fprintf('%d [%f',c,alf(setS(1))); |
---|
94 | %for jj=2:length(setS) |
---|
95 | % fprintf(' %f',alf(setS(jj))); |
---|
96 | %end |
---|
97 | %fprintf(']\n'); |
---|
98 | end |
---|
99 | |
---|
100 | % make the classifier |
---|
101 | W.K = kernel; |
---|
102 | W.par = kpar; |
---|
103 | J = [setS;setE]; |
---|
104 | W.J = J; |
---|
105 | W.sv = X_incremental(J,:); |
---|
106 | W.alf = y(J).*alf(J,:); |
---|
107 | W.b = b; |
---|
108 | w = mapping(mfilename,'trained',W,getlablist(a),k,2); |
---|
109 | w = setname(w,'Inc. Support Vector Classifier'); |
---|
110 | |
---|
111 | else % multi-class classifier: |
---|
112 | |
---|
113 | w = mclassc(a,mapping(mfilename,{ktype,par,C})); |
---|
114 | |
---|
115 | end |
---|
116 | |
---|
117 | else %execution |
---|
118 | W = +ktype; |
---|
119 | [n,d] = size(a); |
---|
120 | laba = getlab(a); |
---|
121 | orga = a; |
---|
122 | a = +a; |
---|
123 | global X_incremental; |
---|
124 | X_incremental = [W.sv; zeros(1,d)]; |
---|
125 | nra = size(W.sv,1)+1; I = 1:nra; |
---|
126 | out = repmat(W.b,n,1); |
---|
127 | for i=1:n |
---|
128 | X_incremental(nra,:) = a(i,:); |
---|
129 | Ka = feval(W.K,W.par,nra,I); |
---|
130 | out(i) = out(i) + Ka(1:(nra-1))*W.alf; |
---|
131 | end |
---|
132 | newout = [out -out]; |
---|
133 | w = setdat(orga,newout,ktype); |
---|
134 | end |
---|
135 | |
---|
136 | return |
---|
137 | |
---|
138 | |
---|
139 | |
---|
140 | function a= unrandomize(a); |
---|
141 | % Unrandomize a dataset; |
---|
142 | |
---|
143 | [n,k,c]=getsize(a); |
---|
144 | if c~=2 |
---|
145 | error('I assume 2 classes'); |
---|
146 | end |
---|
147 | |
---|
148 | nlab = getnlab(a); |
---|
149 | I1 = find(nlab==1); |
---|
150 | I2 = find(nlab==2); |
---|
151 | |
---|
152 | if length(I1)<length(I2) |
---|
153 | cmin = length(I1); |
---|
154 | else |
---|
155 | cmin = length(I2); |
---|
156 | tmpI = I1; |
---|
157 | I1 = I2; |
---|
158 | I2 = tmpI; |
---|
159 | end |
---|
160 | |
---|
161 | J=[]; |
---|
162 | J(1:2:2*cmin) = I1; |
---|
163 | J(2:2:2*cmin) = I2(1:cmin); |
---|
164 | J = [J,I2((cmin+1):end)']; |
---|
165 | a = a(J,:); |
---|
166 | |
---|
167 | return |
---|