svdd.m

来自「模式识别工具箱,希望对大家有用!」· M 代码 · 共 107 行

M
107
字号
%SVDD Support Vector Data Description
% 
%       [W,out,J] = svdd(A,fracrej,fracerr)
% 
% 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. In out
% the raw output of the SVDD is given, and in J the indices of the
% support objects are returned.
%
% Note: in this One-Class problem, there is a clear distinction between
% the target and outlier class. The first object in the dataset is
% considered an target object. All other classes are considered
% outliers.
% 
%       [W,out,J] = svdd(A,[],sigma)
%       [W,out,J] = svdd(A,[],sigma,fracerr)
% 
% When fracrej is empty, but a third parameter is given, this
% parameter is interpreted as the predetermined width of the SVDD.
% 
% See also datasets, mapppings, dd_roc.

% Copyright: D. Tax, R.P.W. Duin, davidt@ph.tn.tudelft.nl
% Faculty of Applied Physics, Delft University of Technology
% P.O. Box 5046, 2600 GA Delft, The Netherlands
  
function [W,out,J] = svdd(a,fracrej,fracerr,param2)

% first set up the parameters
sigma = [];
if nargin >= 3 & isempty(fracrej)
  sigma = fracerr;
  if nargin < 4
    fracerr = 0.0;
  else
    fracerr = param2;
  end
end
if nargin < 3 | isempty(fracerr), fracerr = 0.0; end
if nargin < 2 | isempty(fracrej), fracrej = 0.05; end
if nargin < 1 | isempty(a) % empty svdd
  W = mapping(mfilename,{fracrej,fracerr});
  return
end

if (~isempty(sigma)) | isa(fracrej,'double')   % training

  % introduce outlier label for outlier class if it is not avail.
  if is_ocset(a)
     signlab = -ones(size(a,1),1);
     signlab(find_target(a)) = 1;
  else
     error('SVDD need one-class dataset.');
  end

  % optimize the parameters when required
  Da = +distm(a);
  if isempty(sigma)
    [sigma,alf,R2,J,Dx] = svdd_fmin(Da,signlab,fracrej,fracerr);
  else                             % the user supplied a sigma
    [frac_SV2,alf,R2,Dx,J] = f_svs(sigma,Da,signlab,fracerr);
  end
  offs = 1 + sum(sum((alf(J)*alf(J)').*...
    exp(-distm(+a(J,:),+a(J,:))/(sigma*sigma)),2));

  % store the results
  W.s = sigma;
  W.a = alf(J);
  W.threshold = offs+R2;
  W.sv = +a(J,:);
  W.offs = offs;
  W.scale = mean(offs+Dx);
%  W = {sigma,alf(J),offs+R2,+a(J,:),offs,mean(offs+Dx)};
  W = mapping(mfilename,W,str2mat('target','outlier'),size(a,2),2);
  J = alf;
else                               %testing

  [W,classlist,type,k,c] = mapping(fracrej);  % unpack
  [nlab,lablist,m,k,c,p] = dataset(a);
  if isempty(W.a)                 % check if alpha's are OK
    warning('The SVDD is empty or not well defined');
    out = zeros(m,1);
  end
  % and here we go:
  out = W.offs-sum((ones(m,1)*W.a').*exp(-distm(+a,W.sv)/(W.s*W.s)),2);
  %faking:
  %out = [out (1+1e-8)*ones(m,1)*W.threshold];
  out = [out ones(m,1)*W.threshold];

  % map to probability:
%  newout = dist2dens(out,W.scale);
  % use just distances, but make sure that the correct class has the
  % highest output:
  newout = -out;

  % now lower the threshold a tiny bit.
%  newout(:,2) = newout(:,2)-5*eps;

  W = dataset(newout,getlab(a),classlist,p,lablist);
end
return


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?