ECG-Kit 1.0
(6,042 bytes)
%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 <a href="http://www.37steps.com/faq/faq-regopt/">FAQ</a> 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 (<a href="http://37steps.com/prtools">PRTools Guide</a>)
% 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