⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lds.m

📁 然後稍微檢查一下 tcl、tck 的版本與路徑
💻 M
字号:
function [Yu, err] = lds(Xl,Xu,Yl,rho,opt)% Yu = LDS(Xl,Xu,Yl,rho,opt)%   Run the Low Density Separation algorithm as described in%   "Semi-supervised classification by Low Density Separation" by%   O. Chapelle and A. Zien%% Xl:  d x n matrix with the labeled points% Xu:  d x m matrix with the unlabeled points% Yl:  column vector of length n containing the labels (+1 or -1 for binary)% rho: the constant in (2)% opt: optional structure containing the (optional) fields,%         C:       the soft margin parameter relative to 1/var^2%                  [default = 1]%         nofNn:   number of NN in the graph construction %                  [default = 0, i.e. fully connected graph]%         sigma:   the width of the RBF kernel appearing at the end%                  of 2.1.2, relative to the default value [default = Inf] %         delta:   the threshold in (6) [default = 0.1]%         nofIter: number of iterations for C* to reach C [default = 10]%         Cinit:   initial value for C* relative to C [default = 0.01] %         Cfinal:  final value of C* relative to C [default = 1]%         opt_tb:  uses the optimization toolbox if available [default = 1]%         maxiter: maximum number of iterations in each gradient%                  descent (multiplied by nb of variables) [default = 3]%         tolfun:  stopping criterion on the function value%                  (relative to C) [default = 1e-5]%         verb:    verbosity [default = 1]%         splits:  estimate the test error by cross-validation%                  splits is a cell array containing the indices of the points%                  left out [default = leave-one-out].% Yu: is a real valued output% err: estimated error by cross-validation [cf opt.splits]%  % (C) O. Chapelle and A. Zien, MPI for biol. Cybernetics, Germany% Fill up default values for optif ~exist('opt','var')  opt = [];end;if ~isfield(opt,'delta')       opt.delta       = 0.1;       end;if ~isfield(opt,'nofIter')     opt.nofIter     = 10;        end;if ~isfield(opt,'C')           opt.C           = 1;         end;if ~isfield(opt,'Cinit')       opt.Cinit       = 0.01;      end;if ~isfield(opt,'Cfinal')      opt.Cfinal      = 1;         end;if ~isfield(opt,'nofNn')       opt.nofNn       = 0;         end;if ~isfield(opt,'sigma')       opt.sigma       = Inf;       end;if ~isfield(opt,'opt_tb')      opt.opt_tb      = 1;         end;if ~isfield(opt,'maxiter')     opt.maxiter     = 3;         end;if ~isfield(opt,'tolfun')      opt.tolfun      = 1e-5;      end;if ~isfield(opt,'verb')        opt.verb        = 1;         end;% Check the arguments[ d0, m0 ] = size( Xl );[ d1, m1 ] = size( Xu );if (d0 ~= d1) | ((m0 ~= length(Yl)) & (m0 + m1 ~= length(Yl)))  error('Dimensions mismatch');end;m = m0 + m1;X = [ Xl , Xu ];clear Xl;clear Xu;% assert( 0 <= opt.delta && opt.delta < 1 );assert( 1 <= opt.nofIter );assert( 0 < opt.C );assert( 0 < opt.Cinit && opt.Cinit <= opt.Cfinal );assert( 0 <= opt.nofNn && opt.nofNn <= m );assert( 0 < opt.sigma );if (size(Yl,2) ~= 1)  error(['Third argument should be the label vector']);end;ks = unique( Yl );k = length( ks );if( k < 2 )  error(['At least two different classes (labels in Yl) required']);end;if( k == 2 )  if any(abs(Yl)~=1)    error(['Labels in binary problems must be +/-1']);  end;end;if opt.verb >= 2  fprintf('%d classes, %d labeled points, %d unlabeled, in %d dimension(s)\n',k,m0,m1,d0);end;% Compute the full distance graph ...param.annEps = -1;  % do not use ANN (approximate NN)if opt.verb >= 1  if opt.nofNn == 0       fprintf('Computing  distances ...\n');  else    fprintf('Computing %d nearest neighbors graph ...\n', opt.nofNn);    end;end;[ NN, D2 ] = calcNnDists( X, [], opt.nofNn, param.annEps );% ... and the new metricparam.pathNorm = rho;param.sigma = +inf;param.nofNn = opt.nofNn;if opt.verb >= 1  fprintf('Computing shortest paths ...\n');end;E2 = graphDistKernelC( X, D2, NN, 1:m, param );if( opt.nofNn ~= 0 )  E2 = min( E2,  E2' );  E2( isinf( E2 ) ) = 2 * max( E2( ~isinf( E2 ) ) );end;% Compute the new kernel, do the MDS reduction, ...defaultSigma = calcDefaultSigma( E2(:), 2 );if opt.verb >= 2  fprintf( '  default sigma = %.3f\n', defaultSigma );end;sigma = opt.sigma * defaultSigma;if isinf(sigma)  if any(isinf(E2(:)))    error(['Cannot do the MDS: the graph is not connected'])  end;  [Xmds,E] = mds(E2,opt);else  param.rbf = 'gauss';  K = calcRbfKernel( E2, param.rbf, sigma, 1 );  [Xmds,E] = mds(2-2*K,opt);end;% ... and find the cut p as in (6)if opt.delta >= 0  cond1 = 1-cumsum(E)/sum(E) < opt.delta;  cond2 = E < opt.delta*E(1);  nb_comp = min( find( cond1 & cond2 ) ) - 1;else  nb_comp = length(E);end;if opt.verb >= 2  fprintf('  %d components kept\n',nb_comp);end;Xnldr = Xmds(:,1:nb_comp); % Keep only the first componentsclear Xmds;        % Compute the different values of CdefaultC = 1 / sum(var(Xnldr)); % Default value of C = invert of the varianceif opt.verb >= 2  fprintf( '  default C = %.3f\n', defaultC );end;C = opt.C * defaultC;opt.Cinit = C * opt.Cinit;opt.Cfinal = C * opt.Cfinal;opt.C = C;opt.s = 3; % The constant in L* (4)          % Train the TSVMif opt.verb >= 1  fprintf('Training TSVM')end;if opt.verb >= 2  fprintf('\n')end;Yu = train_one_split( Xnldr, Yl, 1:m0, opt);if nargout==2  % Do the cross-validation  if ~isfield(opt,'splits') % Default = leave-one-out    for i=1:m0      opt.splits{i} = i;    end;  end;  for i = 1:length(opt.splits)    if opt.verb >= 1      fprintf( 'Training split %d\n', i );    end;    val = unique(opt.splits{i});    train = 1:m0;    train(val) = [];    [Yu2, obj(i,:)] = train_one_split( Xnldr, Yl(train), train, opt);    if ( k == 2)      err(i) = mean( Yl( val ) .* Yu2( 1:length(val) ) < 0);    else      [foo, ind] = max( Yu2, [], 2);      ks2 = unique( Yl( train ) );      err(i) = mean( Yl( val ) ~= ks2( ind( 1:length(val) ) ) );    end;  end;  % Add a very tiny bit of the objective function in order to break the  % possible ties during the model selection.  err = err' + 1e-10*mean(obj(:)) / defaultC;end;function [Yu, obj] = train_one_split( Xnldr, Yl, lab, opt)  ks = unique( Yl );  k = length( ks );  Y0 = zeros( size( Xnldr,1), 1 );  if( k == 2 )    if length( Yl ) > length ( lab )      % For debugging: checking local minimum problems      warning(['Initializing with the true labels of the unlabeled points']);      opt.Cinit = opt.Cfinal; opt.nofIter = 1;      [ w0, b, Yu, obj ] = primal_tsvm( Xnldr, Yl, opt);       Y0( lab ) = Yl ( lab );      [ w, b, Yu, obj ] = primal_tsvm( Xnldr, Y0, opt, [w0; b]);      fprintf('   Angle between both normal vectors = %f\n',w0'*w/norm(w0)/norm(w));    else      Y0( lab ) = Yl;      [ w, b, Yu, obj ] = primal_tsvm( Xnldr, Y0, opt);    end;  else    for( c = 1:k )      if opt.verb >= 1        fprintf( 'Training class #%d (label "%d")\n', c, ks(c) );      end;      Y0( lab ) = 2*( Yl == ks(c) ) - 1;      [ w, b, Yu(:,c), obj(c) ] = primal_tsvm( Xnldr, Y0, opt);    end;    obj = sum( obj ); end;function [ w, b, Yu, obj ] = primal_tsvm( X, Y, opt, w0);% === Solve the TSVM problem in the primal  X = [X ones(length(Y),1)]; % Append one dimension for b  % Global variables (not avoid giving them as arguments to obj_fun)  global X_;  X_ =X;           global Xu_; Xu_=X(Y==0,:)'; % To speed-up obj_fun  global R; % Rotation matrix to enforce constraint (5)    % At each step, C* will be multiplied by exponent (2 in the paper)  exponent = (opt.Cfinal/opt.Cinit)^(1/(opt.nofIter+1));  C = opt.C;  C2 = opt.Cinit;  n = size(X,2);    % We want to enforce vbal'*w = cbal  vbal = ones(1,size(X,1));  if any(Y==0)    vbal(Y~=0) = 0;  end;  vbal = vbal*X;  cbal = mean(Y(Y~=0)) * sum(vbal);  % That can be done by rotating w in a new basis which has as  % first component vbal. The first component of w in the new basis  % in then fixed to w1  [R,foo1,foo2] = svd(vbal'); clear foo1 foo2;  w1 = cbal/(vbal*R(:,1));    if nargin<4    % If w0 is given, start with it.    w = zeros(n-1,1);  else    w = R(:,2:end)'*w0;  end;    % Check if the optimization toolbox if available  opt_tb = opt.opt_tb & license('checkout','Optimization_toolbox');    % Initialize the options for the optimizer  maxiter = opt.maxiter*size(X,1);       % Maxinum number of iterations  tolfun = opt.tolfun*C;                 % Stopping criterion  if opt_tb    opt2 = optimset('GradObj','on','LargeScale','off',...                    'Display','off','TolFun',tolfun,'MaxIter',maxiter);    if opt.verb >= 3      opt2 = optimset(opt2,'Display','iter');    end;  else    opt2.length = maxiter;    opt2.tolX = 0;     opt2.tolFun = tolfun;    opt2.verb = opt.verb - 1;  end;     % Main loop  for i = 0:opt.nofIter    C2 = C2*exponent;    if opt.verb == 1, fprintf('.'); end;        if opt_tb      [w,obj,flag,out,grad] = fminunc(@obj_fun,w,opt2,w1,Y,C,C2,opt.s);      iter = out.iterations;    else      [w,fX,count] = minimize(w,@obj_fun,opt2,w1,Y,C,C2,opt.s);      iter = length(fX);      [obj, grad] = obj_fun(w,w1,Y,C,C2,opt.s);      flag = (iter < opt2.length);    end;    if opt.verb >= 2      fprintf(['  Iter = %d\t C* = %f\t Obj = %f [%d iterations, ' ...               'norm of grad = %f]\n'],i,C2,obj,iter,norm(grad));    end;     if ~flag & (opt.verb >= 1)       warning('Maximum number of iterations reached');    end;  end;    % Rotate back w and get w and b  w = R*[w1; w];    Yu = Xu_'*w;  b = w( n );  w = w( 1:n-1 );   if opt.verb == 1, fprintf('\n'); end;   if opt.verb >= 1, fprintf('Done !\n'); end;function [obj,grad] = obj_fun(w,w1,Y,C,C2,s)% Cost function (4)  global X_ Xu_ R    w = R*[w1; w];    out = X_*w;  lab   = find(Y~=0);  unlab = find(Y==0);  sv = find((out.*Y < 1) & (Y~=0));    cost_unlab = exp(-s*out(unlab).^2);  w0 = w;   w0(end)=0;    obj = .5*w0'*w0;  obj = obj + C *sum((1-out(sv).*Y(sv)).^2);  obj = obj + C2*sum(cost_unlab);    grad = w0;  grad = grad + 2*C *X_(sv,:)'*(out(sv)-Y(sv));  tmp = 2*C2*s*cost_unlab.*out(unlab);  grad = grad - Xu_*tmp;  grad = grad'*R; grad = grad(2:end)';function [Y, L] = mds(D,opt)% Classical Multidimensional Scaling.if opt.verb >= 1, fprintf('Computing MDS ...\n'); end;n = length(D);if opt.delta>=0  H = eye(n) - repmat(1/n,n,n);  K = H * (-.5 * D) * H;  [V L] = eig((K+K')./2);  [L ind] = sort(-diag(L));   L = -L;    keep = find(L > 1e-10*max(L));   Y = V(:,ind(keep)) * diag(sqrt(L(keep)));else  k = -opt.delta;  H = eye(n) - repmat(1/n,n,n);  K = H * (-.5 * D) * H;  K = (K+K')/2;    [V L] = eig(K(1:k,1:k));  L = diag(L);  keep = find(L > 1e-10*max(L));   V = V(:,keep) .* repmat(L(keep)'.^(-1/2),k,1);  Y = K(:,1:k)*V;  L = L(keep);end;    

⌨️ 快捷键说明

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