|
楼主 |
发表于 2007-5-20 08:56
|
显示全部楼层
一个SVDD源程序,
%SVDD Support Vector Data Description
%
% W = MYSVDD(A,FRACREJ,SIGMA)
%
% Optimizes a support vector data description for the dataset A by quadratic programming. The data description uses the Gaussian kernel by default. FRACREJ gives the fraction of the target set which will be rejected, when supplied FRACERR gives (an upper bound) for the fraction of data which is completely outside the description.
% versions. This is to make the use of consistent_occ.m possible.
% Further note: this classifier is one of the few which can actually deal with example outlier objects!
%
% Default: FRACREJ=0.05; SIGMA=5 (dangerous!)
%
function W = mysvdd(a,fracrej,sigma)
% First set up the parameters
if nargin < 3
sigma = [];
end
if nargin < 2 | isempty(fracrej), fracrej = 0.05; end
if nargin < 1 | isempty(a) % empty svdd
W = mapping(mfilename,{fracrej,sigma});
W = setname(W,'Support vector data description');
return
end
if isempty(sigma),
sigma = 5;
end
if ~ismapping(fracrej) % training
if isempty(sigma)
error('This versions needs a sigma.');
end
% introduce outlier label for outlier class if it is available.
if isocset(a)
signlab = getoclab(a);
if all(signlab<0), error('SVDD needs target objects!'); end
else
%error('SVDD needs a one-class dataset.');
% Noo, be nice, everything is target:
signlab = ones(size(a,1),1);
%a = target_class(+a);
end
% check the rejection rates
if (length(fracrej)<2) % if no bound on the outlier error is given, we
% do not care
fracrej(2) = 1;
end
if (fracrej(1)>1)
warning('Fracrej > 1? I cannot reject more than all my target data!');
end
% Setup the appropriate C's
nrtar = length(find(signlab==1));
nrout = length(find(signlab==-1));
warning off; % we could get divide by zero, but that is ok.
C(1) = 1/(nrtar*fracrej(1));
C(2) = 1/(nrout*fracrej(2));
warning on;
% Find the alpha's
matver = version;
% Standard optimization procedure:
[alf,R2,Dx,J] = svdd_optrbf(sigma,+a,signlab,C);
SVx = +a(J,:);
alf = alf(J);
% Compute the offset (not important, but now gives the possibility to
% interpret the output as the distance to the center of the sphere)
offs = 1 + sum(sum((alf*alf').*exp(-sqeucldistm(SVx,SVx)/(sigma*sigma)),2));
% store the results
W.j=J;
W.s = sigma;
W.a = alf;
W.threshold = offs+R2;
W.sv = SVx;
W.offs = offs;
W = mapping(mfilename,'trained',W,str2mat('target','outlier'),size(a,2),2);
W = setname(W,'Support vector data description');
else %testing
W = getdata(fracrej);
m = size(a,1);
% check if alpha's are OK
if isempty(W.a)
warning('The SVDD is empty or not well defined');
out = zeros(m,1);
end
% and here we go:
K = exp(-sqeucldistm(+a,W.sv)/(W.s*W.s));
out = W.offs - 2*sum( repmat(W.a',m,1).* K, 2);
newout = [out repmat(W.threshold,m,1)];
% Store the distance as output:
W = setdat(a,-newout,fracrej);
W = setfeatdom(W,{[-inf 0] [-inf 0]});
end
return |
|