60 ClassImp(TMVA::RuleFit);
65 TMVA::RuleFit::RuleFit(
const MethodBase *rfbase)
66 : fVisHistsUseImp( kTRUE )
67 , fLogger(new MsgLogger(
"RuleFit"))
70 fRNGEngine.seed(randSEED);
76 TMVA::RuleFit::RuleFit()
81 , fVisHistsUseImp(kTRUE)
82 , fLogger(new MsgLogger(
"RuleFit"))
84 fRNGEngine.seed(randSEED);
90 TMVA::RuleFit::~RuleFit()
98 void TMVA::RuleFit::InitNEveEff()
100 UInt_t neve = fTrainingEvents.size();
103 fNEveEffTrain = CalcWeightSum( &fTrainingEvents );
110 void TMVA::RuleFit::InitPtrs(
const MethodBase *rfbase )
112 this->SetMethodBase(rfbase);
113 fRuleEnsemble.Initialize(
this );
114 fRuleFitParams.SetRuleFit(
this );
120 void TMVA::RuleFit::Initialize(
const MethodBase *rfbase )
125 fMethodRuleFit->Data()->SetCurrentType(Types::kTraining);
126 UInt_t nevents = fMethodRuleFit->Data()->GetNTrainingEvents();
127 std::vector<const TMVA::Event*> tmp;
128 for (Long64_t ievt=0; ievt<nevents; ievt++) {
129 const Event *
event = fMethodRuleFit->GetEvent(ievt);
130 tmp.push_back(event);
132 SetTrainingEvents( tmp );
141 fRuleEnsemble.MakeModel();
144 fRuleFitParams.Init();
151 void TMVA::RuleFit::SetMethodBase(
const MethodBase *rfbase )
153 fMethodBase = rfbase;
154 fMethodRuleFit =
dynamic_cast<const MethodRuleFit *
>(rfbase);
160 void TMVA::RuleFit::Copy(
const RuleFit& other )
163 fMethodRuleFit = other.GetMethodRuleFit();
164 fMethodBase = other.GetMethodBase();
165 fTrainingEvents = other.GetTrainingEvents();
168 fForest = other.GetForest();
169 fRuleEnsemble = other.GetRuleEnsemble();
176 Double_t TMVA::RuleFit::CalcWeightSum(
const std::vector<const Event *> *events, UInt_t neve )
178 if (events==0)
return 0.0;
179 if (neve==0) neve=events->size();
182 for (UInt_t ie=0; ie<neve; ie++) {
183 sumw += ((*events)[ie])->GetWeight();
191 void TMVA::RuleFit::SetMsgType( EMsgType t )
193 fLogger->SetMinType(t);
194 fRuleEnsemble.SetMsgType(t);
195 fRuleFitParams.SetMsgType(t);
201 void TMVA::RuleFit::BuildTree( DecisionTree *dt )
204 if (fMethodRuleFit==0) {
205 Log() << kFATAL <<
"RuleFit::BuildTree() - Attempting to build a tree NOT from a MethodRuleFit" << Endl;
207 std::vector<const Event *> evevec;
208 for (UInt_t ie=0; ie<fNTreeSample; ie++) {
209 evevec.push_back(fTrainingEventsRndm[ie]);
211 dt->BuildTree(evevec);
212 if (fMethodRuleFit->GetPruneMethod() != DecisionTree::kNoPruning) {
213 dt->SetPruneMethod(fMethodRuleFit->GetPruneMethod());
214 dt->SetPruneStrength(fMethodRuleFit->GetPruneStrength());
222 void TMVA::RuleFit::MakeForest()
224 if (fMethodRuleFit==0) {
225 Log() << kFATAL <<
"RuleFit::BuildTree() - Attempting to build a tree NOT from a MethodRuleFit" << Endl;
227 Log() << kDEBUG <<
"Creating a forest with " << fMethodRuleFit->GetNTrees() <<
" decision trees" << Endl;
228 Log() << kDEBUG <<
"Each tree is built using a random subsample with " << fNTreeSample <<
" events" << Endl;
230 Timer timer( fMethodRuleFit->GetNTrees(),
"RuleFit" );
241 Bool_t useBoost = fMethodRuleFit->UseBoost();
243 if (useBoost) SaveEventWeights();
245 for (Int_t i=0; i<fMethodRuleFit->GetNTrees(); i++) {
247 if (!useBoost) ReshuffleEvents();
250 for (UInt_t ie = 0; ie<fNTreeSample; ie++) {
251 if (fMethodBase->DataInfo().IsSignal(fTrainingEventsRndm[ie])) nsig++;
257 DecisionTree *dt=
nullptr;
258 Bool_t tryAgain=kTRUE;
260 const Int_t ntriesMax=10;
263 frnd = 100*rndGen.Uniform( fMethodRuleFit->GetMinFracNEve(), 0.5*fMethodRuleFit->GetMaxFracNEve() );
265 Bool_t useRandomisedTree = !useBoost;
266 dt =
new DecisionTree( fMethodRuleFit->GetSeparationBase(), frnd, fMethodRuleFit->GetNCuts(), &(fMethodRuleFit->DataInfo()), iclass, useRandomisedTree);
267 dt->SetNVars(fMethodBase->GetNvar());
270 if (dt->GetNNodes()<3) {
275 tryAgain = ((dt==0) && (ntries<ntriesMax));
278 fForest.push_back(dt);
279 if (useBoost) Boost(dt);
283 Log() << kWARNING <<
"------------------------------------------------------------------" << Endl;
284 Log() << kWARNING <<
" Failed growing a tree even after " << ntriesMax <<
" trials" << Endl;
285 Log() << kWARNING <<
" Possible solutions: " << Endl;
286 Log() << kWARNING <<
" 1. increase the number of training events" << Endl;
287 Log() << kWARNING <<
" 2. set a lower min fraction cut (fEventsMin)" << Endl;
288 Log() << kWARNING <<
" 3. maybe also decrease the max fraction cut (fEventsMax)" << Endl;
289 Log() << kWARNING <<
" If the above warning occurs rarely only, it can be ignored" << Endl;
290 Log() << kWARNING <<
"------------------------------------------------------------------" << Endl;
293 Log() << kDEBUG <<
"Built tree with minimum cut at N = " << frnd <<
"% events"
294 <<
" => N(nodes) = " << fForest.back()->GetNNodes()
295 <<
" ; n(tries) = " << ntries
300 if (useBoost) RestoreEventWeights();
309 void TMVA::RuleFit::SaveEventWeights()
311 fEventWeights.clear();
312 for (std::vector<const Event*>::iterator e=fTrainingEvents.begin(); e!=fTrainingEvents.end(); ++e) {
313 Double_t w = (*e)->GetBoostWeight();
314 fEventWeights.push_back(w);
321 void TMVA::RuleFit::RestoreEventWeights()
324 if (fEventWeights.size() != fTrainingEvents.size()) {
325 Log() << kERROR <<
"RuleFit::RestoreEventWeights() called without having called SaveEventWeights() before!" << Endl;
328 for (std::vector<const Event*>::iterator e=fTrainingEvents.begin(); e!=fTrainingEvents.end(); ++e) {
329 (*e)->SetBoostWeight(fEventWeights[ie]);
339 void TMVA::RuleFit::Boost( DecisionTree *dt )
342 Double_t sumwfalse=0;
344 std::vector<Char_t> correctSelected;
346 for (std::vector<const Event*>::iterator e=fTrainingEvents.begin(); e!=fTrainingEvents.end(); ++e) {
347 Bool_t isSignalType = (dt->CheckEvent(*e,kTRUE) > 0.5 );
348 Double_t w = (*e)->GetWeight();
351 if (isSignalType == fMethodBase->DataInfo().IsSignal(*e)) {
352 correctSelected.push_back(kTRUE);
356 correctSelected.push_back(kFALSE);
360 Double_t err = sumwfalse/sumw;
364 Double_t boostWeight = (err>0 ? (1.0-err)/err : 1000.0);
365 Double_t newSumw=0.0;
368 for (std::vector<const Event*>::iterator e=fTrainingEvents.begin(); e!=fTrainingEvents.end(); ++e) {
369 if (!correctSelected[ie])
370 (*e)->SetBoostWeight( (*e)->GetBoostWeight() * boostWeight);
371 newSumw+=(*e)->GetWeight();
375 Double_t scale = sumw/newSumw;
376 for (std::vector<const Event*>::iterator e=fTrainingEvents.begin(); e!=fTrainingEvents.end(); ++e) {
377 (*e)->SetBoostWeight( (*e)->GetBoostWeight() * scale);
379 Log() << kDEBUG <<
"boostWeight = " << boostWeight <<
" scale = " << scale << Endl;
386 void TMVA::RuleFit::ForestStatistics()
388 UInt_t ntrees = fForest.size();
389 if (ntrees==0)
return;
390 const DecisionTree *tree;
394 for (UInt_t i=0; i<ntrees; i++) {
396 nd = Double_t(tree->GetNNodes());
400 Double_t sig = TMath::Sqrt( gTools().ComputeVariance( sumn2, sumn, ntrees ));
401 Log() << kVERBOSE <<
"Nodes in trees: average & std dev = " << sumn/ntrees <<
" , " << sig << Endl;
409 void TMVA::RuleFit::FitCoefficients()
411 Log() << kVERBOSE <<
"Fitting rule/linear terms" << Endl;
412 fRuleFitParams.MakeGDPath();
418 void TMVA::RuleFit::CalcImportance()
420 Log() << kVERBOSE <<
"Calculating importance" << Endl;
421 fRuleEnsemble.CalcImportance();
422 fRuleEnsemble.CleanupRules();
423 fRuleEnsemble.CleanupLinear();
424 fRuleEnsemble.CalcVarImportance();
425 Log() << kVERBOSE <<
"Filling rule statistics" << Endl;
426 fRuleEnsemble.RuleResponseStats();
432 Double_t TMVA::RuleFit::EvalEvent(
const Event& e )
434 return fRuleEnsemble.EvalEvent( e );
440 void TMVA::RuleFit::SetTrainingEvents(
const std::vector<const Event *>& el )
442 if (fMethodRuleFit==0) Log() << kFATAL <<
"RuleFit::SetTrainingEvents - MethodRuleFit not initialized" << Endl;
443 UInt_t neve = el.size();
444 if (neve==0) Log() << kWARNING <<
"An empty sample of training events was given" << Endl;
447 fTrainingEvents.clear();
448 fTrainingEventsRndm.clear();
449 for (UInt_t i=0; i<neve; i++) {
450 fTrainingEvents.push_back(static_cast< const Event *>(el[i]));
451 fTrainingEventsRndm.push_back(static_cast< const Event *>(el[i]));
455 std::shuffle(fTrainingEventsRndm.begin(), fTrainingEventsRndm.end(), fRNGEngine);
458 fNTreeSample =
static_cast<UInt_t
>(neve*fMethodRuleFit->GetTreeEveFrac());
459 Log() << kDEBUG <<
"Number of events per tree : " << fNTreeSample
460 <<
" ( N(events) = " << neve <<
" )"
461 <<
" randomly drawn without replacement" << Endl;
467 void TMVA::RuleFit::GetRndmSampleEvents(std::vector< const Event * > & evevec, UInt_t nevents)
470 if ((nevents<fTrainingEventsRndm.size()) && (nevents>0)) {
471 evevec.resize(nevents);
472 for (UInt_t ie=0; ie<nevents; ie++) {
473 evevec[ie] = fTrainingEventsRndm[ie];
477 Log() << kWARNING <<
"GetRndmSampleEvents() : requested sub sample size larger than total size (BUG!).";
486 void TMVA::RuleFit::NormVisHists(std::vector<TH2F *> & hlist)
488 if (hlist.empty())
return;
495 for (UInt_t i=0; i<hlist.size(); i++) {
497 w = hs->GetMaximum();
498 wm = hs->GetMinimum();
505 if (wm<wmin) wmin=wm;
508 awmin = TMath::Abs(wmin);
509 Double_t usemin,usemax;
522 for (UInt_t i=0; i<hlist.size(); i++) {
525 hs->SetMinimum(usemin);
526 hs->SetMaximum(usemax);
533 void TMVA::RuleFit::FillCut(TH2F* h2,
const Rule *rule, Int_t vind)
539 Bool_t dormin,dormax;
540 Bool_t ruleHasVar = rule->GetRuleCut()->GetCutRange(vind,rmin,rmax,dormin,dormax);
541 if (!ruleHasVar)
return;
543 Int_t firstbin = h2->GetBin(1,1,1);
544 if(firstbin<0) firstbin=0;
545 Int_t lastbin = h2->GetBin(h2->GetNbinsX(),1,1);
546 Int_t binmin=(dormin ? h2->FindBin(rmin,0.5):firstbin);
547 Int_t binmax=(dormax ? h2->FindBin(rmax,0.5):lastbin);
549 Double_t xbinw = h2->GetXaxis()->GetBinWidth(firstbin);
550 Double_t fbmin = h2->GetXaxis()->GetBinLowEdge(binmin-firstbin+1);
551 Double_t lbmax = h2->GetXaxis()->GetBinLowEdge(binmax-firstbin+1)+xbinw;
552 Double_t fbfrac = (dormin ? ((fbmin+xbinw-rmin)/xbinw):1.0);
553 Double_t lbfrac = (dormax ? ((rmax-lbmax+xbinw)/xbinw):1.0);
558 for (Int_t bin = binmin; bin<binmax+1; bin++) {
559 fbin = bin-firstbin+1;
563 else if (bin==binmax) {
569 xc = h2->GetXaxis()->GetBinCenter(fbin);
571 if (fVisHistsUseImp) {
572 val = rule->GetImportance();
575 val = rule->GetCoefficient()*rule->GetSupport();
577 h2->Fill(xc,0.5,val*f);
584 void TMVA::RuleFit::FillLin(TH2F* h2,Int_t vind)
587 if (!fRuleEnsemble.DoLinear())
return;
590 Int_t lastbin = h2->GetNbinsX();
593 if (fVisHistsUseImp) {
594 val = fRuleEnsemble.GetLinImportance(vind);
597 val = fRuleEnsemble.GetLinCoefficients(vind);
599 for (Int_t bin = firstbin; bin<lastbin+1; bin++) {
600 xc = h2->GetXaxis()->GetBinCenter(bin);
601 h2->Fill(xc,0.5,val);
608 void TMVA::RuleFit::FillCorr(TH2F* h2,
const Rule *rule,Int_t vx, Int_t vy)
613 if (fVisHistsUseImp) {
614 val = rule->GetImportance();
617 val = rule->GetCoefficient()*rule->GetSupport();
620 Double_t rxmin, rxmax, rymin, rymax;
621 Bool_t dorxmin, dorxmax, dorymin, dorymax;
625 Bool_t ruleHasVarX = rule->GetRuleCut()->GetCutRange(vx,rxmin,rxmax,dorxmin,dorxmax);
626 Bool_t ruleHasVarY = rule->GetRuleCut()->GetCutRange(vy,rymin,rymax,dorymin,dorymax);
627 if (!(ruleHasVarX || ruleHasVarY))
return;
629 Double_t vxmin = (dorxmin ? rxmin:h2->GetXaxis()->GetXmin());
630 Double_t vxmax = (dorxmax ? rxmax:h2->GetXaxis()->GetXmax());
631 Double_t vymin = (dorymin ? rymin:h2->GetYaxis()->GetXmin());
632 Double_t vymax = (dorymax ? rymax:h2->GetYaxis()->GetXmax());
634 Int_t binxmin = h2->GetXaxis()->FindBin(vxmin);
635 Int_t binxmax = h2->GetXaxis()->FindBin(vxmax);
636 Int_t binymin = h2->GetYaxis()->FindBin(vymin);
637 Int_t binymax = h2->GetYaxis()->FindBin(vymax);
639 Double_t xbinw = h2->GetXaxis()->GetBinWidth(binxmin);
640 Double_t ybinw = h2->GetYaxis()->GetBinWidth(binxmin);
641 Double_t xbinmin = h2->GetXaxis()->GetBinLowEdge(binxmin);
642 Double_t xbinmax = h2->GetXaxis()->GetBinLowEdge(binxmax)+xbinw;
643 Double_t ybinmin = h2->GetYaxis()->GetBinLowEdge(binymin);
644 Double_t ybinmax = h2->GetYaxis()->GetBinLowEdge(binymax)+ybinw;
646 Double_t fxbinmin = (dorxmin ? ((xbinmin+xbinw-vxmin)/xbinw):1.0);
647 Double_t fxbinmax = (dorxmax ? ((vxmax-xbinmax+xbinw)/xbinw):1.0);
648 Double_t fybinmin = (dorymin ? ((ybinmin+ybinw-vymin)/ybinw):1.0);
649 Double_t fybinmax = (dorymax ? ((vymax-ybinmax+ybinw)/ybinw):1.0);
654 for (Int_t binx = binxmin; binx<binxmax+1; binx++) {
658 else if (binx==binxmax) {
664 xc = h2->GetXaxis()->GetBinCenter(binx);
665 for (Int_t biny = binymin; biny<binymax+1; biny++) {
669 else if (biny==binymax) {
675 yc = h2->GetYaxis()->GetBinCenter(biny);
676 h2->Fill(xc,yc,val*fx*fy);
684 void TMVA::RuleFit::FillVisHistCut(
const Rule* rule, std::vector<TH2F *> & hlist)
686 Int_t nhists = hlist.size();
687 Int_t nvar = fMethodBase->GetNvar();
688 if (nhists!=nvar) Log() << kFATAL <<
"BUG TRAP: number of hists is not equal the number of variables!" << Endl;
690 std::vector<Int_t> vindex;
693 for (Int_t ih=0; ih<nhists; ih++) {
694 hstr = hlist[ih]->GetTitle();
695 for (Int_t iv=0; iv<nvar; iv++) {
696 if (fMethodBase->GetInputTitle(iv) == hstr)
697 vindex.push_back(iv);
701 for (Int_t iv=0; iv<nvar; iv++) {
703 if (rule->ContainsVariable(vindex[iv])) {
704 FillCut(hlist[iv],rule,vindex[iv]);
708 FillLin(hlist[iv],vindex[iv]);
715 void TMVA::RuleFit::FillVisHistCorr(
const Rule * rule, std::vector<TH2F *> & hlist)
718 Double_t ruleimp = rule->GetImportance();
719 if (!(ruleimp>0))
return;
720 if (ruleimp<fRuleEnsemble.GetImportanceCut())
return;
722 Int_t nhists = hlist.size();
723 Int_t nvar = fMethodBase->GetNvar();
724 Int_t ncorr = (nvar*(nvar+1)/2)-nvar;
725 if (nhists!=ncorr) Log() << kERROR <<
"BUG TRAP: number of corr hists is not correct! ncorr = "
726 << ncorr <<
" nvar = " << nvar <<
" nhists = " << nhists << Endl;
728 std::vector< std::pair<Int_t,Int_t> > vindex;
729 TString hstr, var1, var2;
732 for (Int_t ih=0; ih<nhists; ih++) {
733 hstr = hlist[ih]->GetName();
734 if (GetCorrVars( hstr, var1, var2 )) {
735 iv1 = fMethodBase->DataInfo().FindVarIndex( var1 );
736 iv2 = fMethodBase->DataInfo().FindVarIndex( var2 );
737 vindex.push_back( std::pair<Int_t,Int_t>(iv2,iv1) );
740 Log() << kERROR <<
"BUG TRAP: should not be here - failed getting var1 and var2" << Endl;
744 for (Int_t ih=0; ih<nhists; ih++) {
745 if ( (rule->ContainsVariable(vindex[ih].first)) ||
746 (rule->ContainsVariable(vindex[ih].second)) ) {
747 FillCorr(hlist[ih],rule,vindex[ih].first,vindex[ih].second);
754 Bool_t TMVA::RuleFit::GetCorrVars(TString & title, TString & var1, TString & var2)
758 if(!title.BeginsWith(
"scat_"))
return kFALSE;
760 TString titleCopy = title(5,title.Length());
761 if(titleCopy.Index(
"_RF2D")>=0) titleCopy.Remove(titleCopy.Index(
"_RF2D"));
763 Int_t splitPos = titleCopy.Index(
"_vs_");
765 var1 = titleCopy(0,splitPos);
766 var2 = titleCopy(splitPos+4, titleCopy.Length());
777 void TMVA::RuleFit::MakeVisHists()
779 const TString directories[5] = {
"InputVariables_Id",
780 "InputVariables_Deco",
781 "InputVariables_PCA",
782 "InputVariables_Gauss",
783 "InputVariables_Gauss_Deco" };
785 const TString corrDirName =
"CorrelationPlots";
787 TDirectory* rootDir = fMethodBase->GetFile();
788 TDirectory* varDir = 0;
789 TDirectory* corrDir = 0;
791 TDirectory* methodDir = fMethodBase->BaseDir();
794 Bool_t done=(rootDir==0);
797 Log() << kWARNING <<
"No basedir - BUG??" << Endl;
801 varDir = (TDirectory*)rootDir->Get( directories[type] );
803 done = ((varDir!=0) || (type>4));
806 Log() << kWARNING <<
"No input variable directory found - BUG?" << Endl;
809 corrDir = (TDirectory*)varDir->Get( corrDirName );
811 Log() << kWARNING <<
"No correlation directory found" << Endl;
812 Log() << kWARNING <<
"Check for other warnings related to correlation histograms" << Endl;
816 Log() << kWARNING <<
"No rulefit method directory found - BUG?" << Endl;
820 varDirName = varDir->GetName();
824 corrDir = (TDirectory *)varDir->Get(corrDirName);
826 Log() << kWARNING <<
"No correlation directory found : " << corrDirName << Endl;
831 Int_t noPlots = ((varDir->GetListOfKeys())->GetEntries()) / 2;
832 Log() << kDEBUG <<
"Got number of plots = " << noPlots << Endl;
835 std::vector<TH2F *> h1Vector;
836 std::vector<TH2F *> h2CorrVector;
837 TIter next(varDir->GetListOfKeys());
839 while ((key = (TKey*)next())) {
841 TClass *cl = gROOT->GetClass(key->GetClassName());
842 if (!cl->InheritsFrom(TH1F::Class()))
continue;
843 TH1F *sig = (TH1F*)key->ReadObj();
844 TString hname= sig->GetName();
845 Log() << kDEBUG <<
"Got histogram : " << hname << Endl;
848 if (hname.Contains(
"__S")){
849 TString htitle = sig->GetTitle();
850 htitle.ReplaceAll(
"signal",
"");
851 TString newname = hname;
852 newname.ReplaceAll(
"__Signal",
"__RF");
853 newname.ReplaceAll(
"__S",
"__RF");
856 TH2F *newhist =
new TH2F(newname,htitle,sig->GetNbinsX(),sig->GetXaxis()->GetXmin(),sig->GetXaxis()->GetXmax(),
857 1,sig->GetYaxis()->GetXmin(),sig->GetYaxis()->GetXmax());
859 h1Vector.push_back( newhist );
865 TIter nextCorr(corrDir->GetListOfKeys());
866 while ((key = (TKey*)nextCorr())) {
868 TClass *cl = gROOT->GetClass(key->GetClassName());
869 if (!cl->InheritsFrom(TH2F::Class()))
continue;
870 TH2F *sig = (TH2F*)key->ReadObj();
871 TString hname= sig->GetName();
874 if ((hname.Contains(
"scat_")) && (hname.Contains(
"_Signal"))) {
875 Log() << kDEBUG <<
"Got histogram (2D) : " << hname << Endl;
876 TString htitle = sig->GetTitle();
877 htitle.ReplaceAll(
"(Signal)",
"");
878 TString newname = hname;
879 newname.ReplaceAll(
"_Signal",
"_RF2D");
883 TH2F *newhist =
new TH2F(newname,htitle,
884 sig->GetNbinsX()/rebin,sig->GetXaxis()->GetXmin(),sig->GetXaxis()->GetXmax(),
885 sig->GetNbinsY()/rebin,sig->GetYaxis()->GetXmin(),sig->GetYaxis()->GetXmax());
886 if (GetCorrVars( newname, var1, var2 )) {
887 Int_t iv1 = fMethodBase->DataInfo().FindVarIndex(var1);
888 Int_t iv2 = fMethodBase->DataInfo().FindVarIndex(var2);
890 sig->GetYaxis()->SetTitle(var1);
893 sig->GetYaxis()->SetTitle(fMethodBase->GetInputTitle(iv1));
896 sig->GetXaxis()->SetTitle(var2);
899 sig->GetXaxis()->SetTitle(fMethodBase->GetInputTitle(iv2));
903 h2CorrVector.push_back( newhist );
909 UInt_t nrules = fRuleEnsemble.GetNRules();
911 for (UInt_t i=0; i<nrules; i++) {
912 rule = fRuleEnsemble.GetRulesConst(i);
913 FillVisHistCut(rule, h1Vector);
916 FillVisHistCut(0, h1Vector);
917 NormVisHists(h1Vector);
922 for (UInt_t i=0; i<nrules; i++) {
923 rule = fRuleEnsemble.GetRulesConst(i);
924 FillVisHistCorr(rule, h2CorrVector);
926 NormVisHists(h2CorrVector);
930 for (UInt_t i=0; i<h1Vector.size(); i++) h1Vector[i]->Write();
931 for (UInt_t i=0; i<h2CorrVector.size(); i++) h2CorrVector[i]->Write();
937 void TMVA::RuleFit::MakeDebugHists()
939 TDirectory* methodDir = fMethodBase->BaseDir();
941 Log() << kWARNING <<
"<MakeDebugHists> No rulefit method directory found - bug?" << Endl;
946 std::vector<Double_t> distances;
947 std::vector<Double_t> fncuts;
948 std::vector<Double_t> fnvars;
951 Double_t dABmin=1000000.0;
952 Double_t dABmax=-1.0;
953 UInt_t nrules = fRuleEnsemble.GetNRules();
954 for (UInt_t i=0; i<nrules; i++) {
955 ruleA = fRuleEnsemble.GetRulesConst(i);
956 for (UInt_t j=i+1; j<nrules; j++) {
957 ruleB = fRuleEnsemble.GetRulesConst(j);
958 Double_t dAB = ruleA->RuleDist( *ruleB, kTRUE );
960 UInt_t nc = ruleA->GetNcuts();
961 UInt_t nv = ruleA->GetNumVarsUsed();
962 distances.push_back(dAB);
963 fncuts.push_back(static_cast<Double_t>(nc));
964 fnvars.push_back(static_cast<Double_t>(nv));
965 if (dAB<dABmin) dABmin=dAB;
966 if (dAB>dABmax) dABmax=dAB;
971 TH1F *histDist =
new TH1F(
"RuleDist",
"Rule distances",100,dABmin,dABmax);
972 TTree *distNtuple =
new TTree(
"RuleDistNtuple",
"RuleDist ntuple");
976 distNtuple->Branch(
"dist", &ntDist,
"dist/D");
977 distNtuple->Branch(
"ncuts",&ntNcuts,
"ncuts/D");
978 distNtuple->Branch(
"nvars",&ntNvars,
"nvars/D");
980 for (UInt_t i=0; i<distances.size(); i++) {
981 histDist->Fill(distances[i]);
982 ntDist = distances[i];