%REGOPTC Optimise regularisation and complexity parameters by crossvalidation % % [W,PARS] = REGOPTC(A,CLASSF,PARS,DEFS,NPAR,PAR_MIN_MAX,TESTFUN,REALINT) % % INPUT % A Dataset, training set % CLASSF String containing the name of the classifier routine. % PARS Cell array with parameters for CLASSF % DEFS Defaults for PARS % NPAR Index in PARS of parameters to be optimised % PAR_MIN_MAX Minimum and maximum values of the search interval for % the parameters to be optimised % TESTFUN Criterion function to be minimized, default TESTC % REALINT 0/1 vector, indicating for every parameter in PARS whether % it is real (1) or integer (0). Default: all real. % % OUTPUT % W Best classifier, trained by A % PARS Resulting parameter vector % % DESCRIPTION % This routine is used inside classifiers and mappings to optimise a % regularisation or complexity parameter. Using cross-validation the % performance of the classifier is estimated using TESTFUN (e.g. TESTC). % Matlab's FMINBND is used for the optimisation. Only the parameters in % PARS that are set to NaN are optimised. For the other ones the given % values are used in the internal calls to CLASSF in REGOPTC. In case % mulitple parameters are set to NaN they are optimised in the order % supplied by NPAR. % % The final parameters PARS can also be retrieved by GETOPT_PARS. This is % useful if W is optimised inside training a classifier that does not % return these parameters in the output. % % For examples of usage inside a classifier see LDC and SVC. Consequently % LDC can be called as in the below example. % % Some globals are used to specify the optimization. Users may change them % by PRGLOBAL. See the FAQ on this topic. % % EXAMPLE % A = gendatd([30 30],50); % W = ldc(A,0,NaN); % set first reg par to 0 and optimise second. % getopt_pars % retrieve optimal paameter set % % SEE ALSO (PRTools Guide) % DATASETS, MAPPINGS, PRCROSSVAL, TESTC, GETOPT_PARS, PRGLOBAL % Copyright: R.P.W. Duin, r.p.w.duin@37steps.com % Faculty EWI, Delft University of Technology % P.O. Box 5031, 2600 GA Delft, The Netherlands function [w,varargout] = regoptc(a,classf,parms,defs,regparnum,regparmin_max,testfunc,realint) global REGOPT_NFOLDS REGOPT_REPS REGOPT_ITERMAX REGOPT_ITER REGOPT_OPTCRIT REGOPT_PARS if isempty(REGOPT_NFOLDS), REGOPT_NFOLDS = 5; end if isempty(REGOPT_REPS), REGOPT_REPS = 1; end if isempty(REGOPT_ITERMAX), REGOPT_ITERMAX = 20; end REGOPT_OPTCRIT = inf; REGOPT_PARS = []; isdataset(a); isuntrained(feval(classf,[],parms{:})); if nargin < 8, realint = ones(1,length(parms)); end if nargin < 7, testfunc = testc([],'crisp'); end % if (length(parms) ~= length(defs)) | (length(parms) < max(regparnum)) | ... % (length(parms) ~= size(regparmin_max,1)) | (length(regparnum) ~= length(realint)) | ... % (size(regparmin_max,2) ~= 2) % error('Some parameters have wrong size') % end if (length(parms) ~= length(defs)) | (length(parms) < max(regparnum)) | ... (length(parms) ~= size(regparmin_max,1)) | (length(parms) ~= length(realint)) | ... (size(regparmin_max,2) ~= 2) error('Some parameters have wrong size') end J = []; K = zeros(1,length(parms)); for j=1:length(parms) if ~isempty(parms{j}) & ~ismapping(parms{j}) & ~isstruct(parms{j}) & isnan(parms{j}) J = [J j]; K(j) = 1; % parameters to be optimised end end parms(J) = defs(J); % store defaults (needed in case of optimal parameters) matwarn = warning; warning off prwarn = prwarning; prwarning(0); prwaitbar(length(regparnum),'Parameter optimization'); for j=1:length(regparnum) prwaitbar(length(regparnum),j); n = regparnum(j); if K(n) regparmin = regparmin_max(n,1); regparmax = regparmin_max(n,2); if regparmin > 0 & regparmax > 0 & realint(n) % if interval positive and real setlog = 1; % better to use logarithmic scaling regparmin = log(regparmin); regparmax = log(regparmax); else setlog = 0; end REGOPT_ITER = 0; %if length(regparnum) == 1 prprogress([],' par optim: %i steps, %i folds: \n', ... REGOPT_ITERMAX,REGOPT_NFOLDS); %else % prprogress([],'%i-par optim: %i, %i steps, %i folds: \n', ... % length(regparnum),n,REGOPT_ITERMAX,REGOPT_NFOLDS); %end prwaitbar(REGOPT_ITERMAX,'Parameter optimization'); if realint(n) == 1 regpar = fminbnd(@evalregcrit,regparmin,regparmax, ... optimset('Display','off','maxiter',REGOPT_ITERMAX), ... classf,a,parms,n,setlog,REGOPT_NFOLDS,REGOPT_REPS,testfunc,1); else regpar = nfminbnd(@evalregcrit,regparmin,regparmax,REGOPT_ITERMAX, ... classf,a,parms,n,setlog,REGOPT_NFOLDS,REGOPT_REPS,testfunc,0); end prwaitbar(0) if setlog parms{n} = exp(regpar); else parms{n} = regpar; end end end prwaitbar(0); varargout = cell(1,nargout-1); [w,varargout{:}] = feval(classf,a,parms{:}); REGOPT_PARS = parms; warning(matwarn); prwarning(prwarn); return function regcrit = evalregcrit(regpar,classf,a,parms,regparnum, ... setlog,nfolds,reps,testfunc,realint); global REGOPT_ITER REGOPT_OPTCRIT REGOPT_ITERMAX REGOPT_ITER = REGOPT_ITER+1; prwaitbar(REGOPT_ITERMAX,REGOPT_ITER); if setlog parms{regparnum} = exp(regpar); else parms{regparnum} =regpar; end if realint prprogress([],' %i %5.3f %6.2e \n',REGOPT_ITER,REGOPT_OPTCRIT,parms{regparnum}); else prprogress([],' %i %5.3f %i \n',REGOPT_ITER,REGOPT_OPTCRIT,parms{regparnum}); end w = feval(classf,[],parms{:}); randstate = randreset(1); regcrit = prcrossval(a,w,nfolds,reps,testfunc); % use soft error as criterion (more smooth) randreset(randstate); REGOPT_OPTCRIT = min(mean(regcrit),REGOPT_OPTCRIT); return