www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/@modeldev/buildmodels.m
function OK = buildmodels(mdev,mlist,varargin) %BUILDMODELS build list of child models % % OK= buildmodels(mdev,mlist,Criteria) % Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. p= address(mdev); if nargin<2 m= model(mdev); s= statistics(mdev); nobs= s(1); % choose model template from dialog [mlist,OK]=xreg_modeltemplates('create',m,nobs); if ~OK return end end % Initalise display DispObj= iMakeDispObj(mdev); % Selection criteria [Criteria,OK] = iChooseCriteria(mlist,DispObj,varargin{:}); % remove invalid models [mlist,mdlsOK]= iCheckModels(mlist,DispObj); if OK && mdlsOK % choose whether to build parallel or serial doPARFOR = mbcfoundation.DCTManager.isParpoolOpen(); if doPARFOR fBuild = @iBuildParallel; else fBuild = @iBuildSerial; end N= length(mlist); DispObj= iCreateDisplay(DispObj,N+1); % prepare models for build mlist= iPrepareModels(mlist,mdev,Criteria); ExistingChildren = p.numChildren; % main build - either serial or parallel fBuild(p,mlist,DispObj); % display progress iDisplayProgress(DispObj,'Finished building models',length(mlist)+1) % choose best model iChooseBest(p,Criteria); % clean up progress display iDeleteProgress(DispObj,mdev) OK = p.numChildren>ExistingChildren; else OK = false; end function stopped = iBuildSerial(p,mlist,DispObj) %iBUILDSERIAL build models using ordinary for loop and display progress % % stopped = iBuildSerial(p,mlist,DispObj) N = length(mlist); stopped = false; for i = 1:N; % prepare model for adding to tree mi = mlist{i}; % build new child pch= modeldev(mi,p,false,false); % Display Progress iDisplayProgress(DispObj,... sprintf('Building model for %s/%s...',p.name,name(mi)),i); try % fit it fitmodel(pch.info); pch.name(name(mi)); % clean up any temporary store in models pch.cleanup; % display new item on tree iDisplayTree(DispObj,pch) % delete any plot figures figs = findobj(allchild(0),'flat','Tag','mbcfitplot'); if ~isempty(figs) delete(figs) end catch %#ok<CTCH> % model fit crashed so delete pch.delete; end drawnow if iStop(DispObj) stopped = true; break end end function stopped = iBuildParallel(p,mlist,DispObj) %IBUILDPARALLEL build models using parfor - no display progress % % stopped = iBuildParallel(p,mlist,DispObj) % can't stop stopped = false; n = length(mlist); [X,Y] = p.getdata; % make data into double for size X = double(X); Y = double(Y); % Display Progress iDisplayProgress(DispObj,... sprintf('Building models for %s in parallel...',p.name),1); % set up outputs OK = false(1,n); mout = cell(1,n); Stats = cell(1,n); % reorder on the assumption that models are of increasing complexity. This % is reasonable for increasing number of centers for RBFs index = [1:2:n,2:2:n]; mlist = mlist(index); pp = gcp; for i=1:n % fit model f(i) = parfeval(pp,@iFitModel,3,mlist{i},X,Y); end results = cell(1,3); hasRun = false(1,n); for i=1:n [idx,results{1:3}] = fetchNext(f); [mout{idx},OK(idx),Stats{idx}]= results{:}; hasRun(idx) = true; if OK(idx) iDisplayProgress(DispObj,... sprintf('Building model for %s/%s...',p.name,name(mout{idx})),i); else iDisplayProgress(DispObj,... sprintf('Fit failed for %d...',idx),i); end if iStop(DispObj) stopped = true; break end end if stopped mout = mout(hasRun); OK = OK(hasRun); Stats = Stats(hasRun); index = index(hasRun); cancel(f); end % delete any plot figures figs = findobj(allchild(0),'flat','Tag','mbcfitplot'); if ~isempty(figs) delete(figs) end % make modeldev and set up model - this needs to be done in the original % order [~,index] = sort(index); for i=index if ~isempty(mout{i}) % make child modeldev with fitted model pch= modeldev(mout{i},p,false,false); mdev = pch.info; mdev.Statistics = Stats{i}; mdev = status(mdev,OK(i)); % name node pch.name(name(mdev.Model)); % display new item on tree iDisplayTree(DispObj,pch) end end function [m,OK,S] = iFitModel(m,X,Y) %iFITMODEL fit model for parfor loop % % [m,OK,S] = iFitModel(m,X,Y) try [m,OK,S]= fitmodel(m,X,Y); % reduce size of data m = cleanup(m); catch %#ok<CTCH> % set model to empty if fitmodel crashes so we can delete it m = []; S = []; OK = false; end function mlist= iPrepareModels(mlist,mdev,Criteria) %IPREPAREMODELS prepare models for building % % mlist= iPrepareModels(mlist,p,Criteria) % resolve boxcox, reset model and make sure selection criteria is in % summary statistics [~,Y,DataOK] = FitData(mdev); m = model(mdev); Yraw = double(Y(DataOK)); for i = 1:length(mlist) mi = mlist{i}; % prepare model for adding to tree lam= get(mi,'boxcox'); fopt= get(mi,'fitalg'); mi = copymodel(m,mi); % Make sure selection criteria is present if ~ismember(Criteria, StatsList(mi)) mi= addSummaryStats(mi,Criteria ); end set(mi,'fitalg',fopt); % reset after copy model as rbf/reset requires this mi= reset(mi); % deal wirh box cox transform (this gets removed by copymodel!) if lam~=1 set(mi,'boxcox',{lam,Yraw}) else set(mi,'ytrans',''); end mlist{i} = mi; end function [mlist,OK]= iCheckModels(mlist,DispObj) %ICHECKMODELS check models before build to remove any invalid models % % [mlist,OK]= iCheckModels(mlist,DispObj) % remove invalid models mok= false(1,length(mlist)); BadModelList= ''; for i=1:length(mlist) if isstruct(mlist{i}) % object didn't load properly mok(i)= false; BadModelList= sprintf('%s,<Invalid model>',BadModelList); else try mok(i)= checkmodel(mlist{i}); catch %#ok<CTCH> mok(i)= false; BadModelList= sprintf('%s,%s',BadModelList,name(mlist{i})); end end end if ~all(mok) iDisplayMessage(DispObj,sprintf('Invalid models %s removed from template',BadModelList)) end mlist= mlist(mok); OK = any(mok); function [Criteria,OK] = iChooseCriteria(mlist,DispObj,Criteria) %ICHOOSECRITERIA choose selection criteria % % [Criteria,OK] = iChooseCriteria(mlist,Criteria) OK = true; % make an xregmulti to check selection criteria mm= xregmulti('nfactors',nfactors(mlist{1})); set(mm,'models',mlist); if nargin<=2 % default selection criteria [~,List]=childstats(mm); if any(strcmp('AICc',List)) Criteria= 'AICc'; elseif any(strcmp('PRESS RMSE',List)) Criteria= 'PRESS RMSE'; else Criteria= 'RMSE'; end if DispObj.GUIMode [Criteria,OK]= guiSelectCriteria(mm,Criteria); drawnow update end else % check selection criteria is available [~,Chead]= childstats(mm); if ~any(strcmp(Criteria,Chead)) Criteria= 'RMSE'; end end function iChooseBest(p,Criteria) %ICHOOSEBEST choose best model based on Criteria % % iChooseBest(p,Criteria) FittedChildren= p.children(@status); FittedChildren=find([FittedChildren{:}]~=0); % choose best model based on Criteria if ~isempty(FittedChildren) [S,Chead]= childstats(info(p)); ind= find(strcmp(Criteria,Chead)); if isempty(ind) % use RMSE by default Criteria= 'RMSE'; ind= find(strcmp(Criteria,Chead)); end % determine whether to minimize or maximize selection criteria mi = p.children(1,@model); [List,~,~,MinIsBest]= StatsList(mi{1}); % select best model from fitted models if MinIsBest(strcmp(Chead{ind},List)) [~,BestInd]=min(S(FittedChildren,ind)); else [~,BestInd]=max(S(FittedChildren,ind)); end %index of best accounting for unfitted models BestInd = FittedChildren(BestInd); if ~isempty(BestInd) % select best model if there is one p.BestModel(p.children(BestInd)); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Display progress function DispObj= iMakeDispObj(mdev) % Check whether running with model browser DispObj.GUIMode = isBrowserProject(mdev); function DispObj= iCreateDisplay(DispObj,ProgressLength) if DispObj.GUIMode && ProgressLength>1 mbh= MBrowser; DispObj.mbh= mbh; DispObj.OldPtr= get(mbh.Figure,'Pointer'); set(mbh.Figure,'Pointer','watch'); % create waitbar hWB = xregGui.waitdlg('parent',mbh.Figure,'ShowStopButton',true); set(hWB.waitbar,'Min',1,'Max',ProgressLength); DispObj.hWB= hWB; end function stop = iStop(DispObj) if DispObj.GUIMode drawnow update stop = DispObj.hWB.StopState; else stop = false; end function iDisplayProgress(DispObj,msg,progress) if DispObj.GUIMode hWB= DispObj.hWB; hWB.message= msg; if nargin>2 hWB.Waitbar.Value= progress; end drawnow('expose'); end function iDisplayTree(DispObj,pch) if DispObj.GUIMode % add it to mbrowser tree DispObj.mbh.treeview(pch,'add'); end function iDisplayMessage(DispObj,msg,Title) if DispObj.GUIMode if nargin<3 Title= 'Build Models'; end h= msgbox(msg,Title,'modal'); uiwait(h) end function iDeleteProgress(DispObj,mdev) if DispObj.GUIMode mbh= DispObj.mbh; delete(DispObj.hWB); set(mbh.Figure,'Pointer',DispObj.OldPtr); end