ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MethodBoost.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss,Or Cohen, Jan Therhaag, Eckhard von Toerne
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : MethodCompositeBase *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Virtual base class for all MVA method *
12  * *
13  * Authors (alphabetical): *
14  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
15  * Peter Speckmayer <Peter.Speckmazer@cern.ch> - CERN, Switzerland *
16  * Joerg Stelzer <Joerg.Stelzer@cern.ch> - CERN, Switzerland *
17  * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
18  * Jan Therhaag <Jan.Therhaag@cern.ch> - U of Bonn, Germany *
19  * Eckhard v. Toerne <evt@uni-bonn.de> - U of Bonn, Germany *
20  * *
21  * Copyright (c) 2005-2011: *
22  * CERN, Switzerland *
23  * U. of Victoria, Canada *
24  * MPI-K Heidelberg, Germany *
25  * U. of Bonn, Germany *
26  * *
27  * Redistribution and use in source and binary forms, with or without *
28  * modification, are permitted according to the terms listed in LICENSE *
29  * (http://tmva.sourceforge.net/LICENSE) *
30  **********************************************************************************/
31 
32 //_______________________________________________________________________
33 //
34 // This class is meant to boost a single classifier. Boosting means //
35 // training the classifier a few times. Everytime the wieghts of the //
36 // events are modified according to how well the classifier performed //
37 // on the test sample. //
38 ////////////////////////////////////////////////////////////////////////////////
39 
40 #include <algorithm>
41 #include <iomanip>
42 #include <vector>
43 #include <cmath>
44 
45 #include "Riostream.h"
46 #include "TRandom3.h"
47 #include "TMath.h"
48 #include "TObjString.h"
49 #include "TH1F.h"
50 #include "TH2F.h"
51 #include "TGraph.h"
52 #include "TSpline.h"
53 #include "TDirectory.h"
54 #include "TTree.h"
55 
56 #include "TMVA/ClassifierFactory.h"
57 #include "TMVA/Config.h"
58 #include "TMVA/DataSet.h"
59 #include "TMVA/DataSetInfo.h"
60 #include "TMVA/IMethod.h"
61 #include "TMVA/MethodBase.h"
62 #include "TMVA/MethodBoost.h"
63 #include "TMVA/MethodCategory.h"
65 #include "TMVA/MethodDT.h"
66 #include "TMVA/MethodFisher.h"
67 #include "TMVA/PDF.h"
68 #include "TMVA/Results.h"
69 #include "TMVA/Timer.h"
70 #include "TMVA/Tools.h"
71 #include "TMVA/Types.h"
72 
73 #include "TMVA/SeparationBase.h"
75 #include "TMVA/GiniIndex.h"
76 #include "TMVA/CrossEntropy.h"
79 
80 REGISTER_METHOD(Boost)
81 
82 ClassImp(TMVA::MethodBoost)
83 
84 ////////////////////////////////////////////////////////////////////////////////
85 
86 TMVA::MethodBoost::MethodBoost( const TString& jobName,
87  const TString& methodTitle,
88  DataSetInfo& theData,
89  const TString& theOption,
90  TDirectory* theTargetDir ) :
91  TMVA::MethodCompositeBase( jobName, Types::kBoost, methodTitle, theData, theOption, theTargetDir )
92  , fBoostNum(0)
93  , fDetailedMonitoring(kFALSE)
94  , fAdaBoostBeta(0)
95  , fRandomSeed(0)
96  , fBaggedSampleFraction(0)
97  , fBoostedMethodTitle(methodTitle)
98  , fBoostedMethodOptions(theOption)
99  , fMonitorBoostedMethod(kFALSE)
100  , fMonitorTree(0)
101  , fBoostWeight(0)
102  , fMethodError(0)
103  , fROC_training(0.0)
104  , fOverlap_integral(0.0)
105  , fMVAvalues(0)
106 {
107  fMVAvalues = new std::vector<Float_t>;
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 
113  const TString& theWeightFile,
114  TDirectory* theTargetDir )
115  : TMVA::MethodCompositeBase( Types::kBoost, dsi, theWeightFile, theTargetDir )
116  , fBoostNum(0)
117  , fDetailedMonitoring(kFALSE)
118  , fAdaBoostBeta(0)
119  , fRandomSeed(0)
120  , fBaggedSampleFraction(0)
121  , fBoostedMethodTitle("")
122  , fBoostedMethodOptions("")
123  , fMonitorBoostedMethod(kFALSE)
124  , fMonitorTree(0)
125  , fBoostWeight(0)
126  , fMethodError(0)
127  , fROC_training(0.0)
128  , fOverlap_integral(0.0)
129  , fMVAvalues(0)
130 {
131  fMVAvalues = new std::vector<Float_t>;
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// destructor
136 
138 {
139  fMethodWeight.clear();
140 
141  // the histogram themselves are deleted when the file is closed
142 
143  fTrainSigMVAHist.clear();
144  fTrainBgdMVAHist.clear();
145  fBTrainSigMVAHist.clear();
146  fBTrainBgdMVAHist.clear();
147  fTestSigMVAHist.clear();
148  fTestBgdMVAHist.clear();
149 
150  if (fMVAvalues) {
151  delete fMVAvalues;
152  fMVAvalues = 0;
153  }
154 }
155 
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// Boost can handle classification with 2 classes and regression with one regression-target
159 
161 {
162  if (type == Types::kClassification && numberClasses == 2) return kTRUE;
163  // if (type == Types::kRegression && numberTargets == 1) return kTRUE;
164  return kFALSE;
165 }
166 
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 
171 {
172  DeclareOptionRef( fBoostNum = 1, "Boost_Num",
173  "Number of times the classifier is boosted" );
174 
175  DeclareOptionRef( fMonitorBoostedMethod = kTRUE, "Boost_MonitorMethod",
176  "Write monitoring histograms for each boosted classifier" );
177 
178  DeclareOptionRef( fDetailedMonitoring = kFALSE, "Boost_DetailedMonitoring",
179  "Produce histograms for detailed boost monitoring" );
180 
181  DeclareOptionRef( fBoostType = "AdaBoost", "Boost_Type", "Boosting type for the classifiers" );
182  AddPreDefVal(TString("RealAdaBoost"));
183  AddPreDefVal(TString("AdaBoost"));
184  AddPreDefVal(TString("Bagging"));
185 
186  DeclareOptionRef(fBaggedSampleFraction=.6,"Boost_BaggedSampleFraction","Relative size of bagged event sample to original size of the data sample (used whenever bagging is used)" );
187 
188  DeclareOptionRef( fAdaBoostBeta = 1.0, "Boost_AdaBoostBeta",
189  "The ADA boost parameter that sets the effect of every boost step on the events' weights" );
190 
191  DeclareOptionRef( fTransformString = "step", "Boost_Transform",
192  "Type of transform applied to every boosted method linear, log, step" );
193  AddPreDefVal(TString("step"));
194  AddPreDefVal(TString("linear"));
195  AddPreDefVal(TString("log"));
196  AddPreDefVal(TString("gauss"));
197 
198  DeclareOptionRef( fRandomSeed = 0, "Boost_RandomSeed",
199  "Seed for random number generator used for bagging" );
200 
201  TMVA::MethodCompositeBase::fMethods.reserve(fBoostNum);
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// options that are used ONLY for the READER to ensure backward compatibility
206 /// they are hence without any effect (the reader is only reading the training
207 /// options that HAD been used at the training of the .xml weightfile at hand
208 
210 {
211 
213 
214  DeclareOptionRef( fHistoricOption = "ByError", "Boost_MethodWeightType",
215  "How to set the final weight of the boosted classifiers" );
216  AddPreDefVal(TString("ByError"));
217  AddPreDefVal(TString("Average"));
218  AddPreDefVal(TString("ByROC"));
219  AddPreDefVal(TString("ByOverlap"));
220  AddPreDefVal(TString("LastMethod"));
221 
222  DeclareOptionRef( fHistoricOption = "step", "Boost_Transform",
223  "Type of transform applied to every boosted method linear, log, step" );
224  AddPreDefVal(TString("step"));
225  AddPreDefVal(TString("linear"));
226  AddPreDefVal(TString("log"));
227  AddPreDefVal(TString("gauss"));
228 
229  // this option here
230  //DeclareOptionRef( fBoostType = "AdaBoost", "Boost_Type", "Boosting type for the classifiers" );
231  // still exists, but these two possible values
232  AddPreDefVal(TString("HighEdgeGauss"));
233  AddPreDefVal(TString("HighEdgeCoPara"));
234  // have been deleted .. hope that works :)
235 
236  DeclareOptionRef( fHistoricBoolOption, "Boost_RecalculateMVACut",
237  "Recalculate the classifier MVA Signallike cut at every boost iteration" );
238 
239 }
240 ////////////////////////////////////////////////////////////////////////////////
241 /// just registering the string from which the boosted classifier will be created
242 
243 Bool_t TMVA::MethodBoost::BookMethod( Types::EMVA theMethod, TString methodTitle, TString theOption )
244 {
245  fBoostedMethodName = Types::Instance().GetMethodName( theMethod );
246  fBoostedMethodTitle = methodTitle;
247  fBoostedMethodOptions = theOption;
248  TString opts=theOption;
249  opts.ToLower();
250 // if (opts.Contains("vartransform")) Log() << kFATAL << "It is not possible to use boost in conjunction with variable transform. Please remove either Boost_Num or VarTransform from the option string"<< methodTitle<<Endl;
251 
252  return kTRUE;
253 }
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 
258 {
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// initialisation routine
263 
265 {
266 
267  Results* results = Data()->GetResults(GetMethodName(), Types::kTraining, GetAnalysisType());
268 
269  results->Store(new TH1F("MethodWeight","Normalized Classifier Weight",fBoostNum,0,fBoostNum),"ClassifierWeight");
270  results->Store(new TH1F("BoostWeight","Boost Weight",fBoostNum,0,fBoostNum),"BoostWeight");
271  results->Store(new TH1F("ErrFraction","Error Fraction (by boosted event weights)",fBoostNum,0,fBoostNum),"ErrorFraction");
272  if (fDetailedMonitoring){
273  results->Store(new TH1F("ROCIntegral_test","ROC integral of single classifier (testing sample)",fBoostNum,0,fBoostNum),"ROCIntegral_test");
274  results->Store(new TH1F("ROCIntegralBoosted_test","ROC integral of boosted method (testing sample)",fBoostNum,0,fBoostNum),"ROCIntegralBoosted_test");
275  results->Store(new TH1F("ROCIntegral_train","ROC integral of single classifier (training sample)",fBoostNum,0,fBoostNum),"ROCIntegral_train");
276  results->Store(new TH1F("ROCIntegralBoosted_train","ROC integral of boosted method (training sample)",fBoostNum,0,fBoostNum),"ROCIntegralBoosted_train");
277  results->Store(new TH1F("OverlapIntegal_train","Overlap integral (training sample)",fBoostNum,0,fBoostNum),"Overlap");
278  }
279 
280 
281  results->GetHist("ClassifierWeight")->GetXaxis()->SetTitle("Index of boosted classifier");
282  results->GetHist("ClassifierWeight")->GetYaxis()->SetTitle("Classifier Weight");
283  results->GetHist("BoostWeight")->GetXaxis()->SetTitle("Index of boosted classifier");
284  results->GetHist("BoostWeight")->GetYaxis()->SetTitle("Boost Weight");
285  results->GetHist("ErrorFraction")->GetXaxis()->SetTitle("Index of boosted classifier");
286  results->GetHist("ErrorFraction")->GetYaxis()->SetTitle("Error Fraction");
287  if (fDetailedMonitoring){
288  results->GetHist("ROCIntegral_test")->GetXaxis()->SetTitle("Index of boosted classifier");
289  results->GetHist("ROCIntegral_test")->GetYaxis()->SetTitle("ROC integral of single classifier");
290  results->GetHist("ROCIntegralBoosted_test")->GetXaxis()->SetTitle("Number of boosts");
291  results->GetHist("ROCIntegralBoosted_test")->GetYaxis()->SetTitle("ROC integral boosted");
292  results->GetHist("ROCIntegral_train")->GetXaxis()->SetTitle("Index of boosted classifier");
293  results->GetHist("ROCIntegral_train")->GetYaxis()->SetTitle("ROC integral of single classifier");
294  results->GetHist("ROCIntegralBoosted_train")->GetXaxis()->SetTitle("Number of boosts");
295  results->GetHist("ROCIntegralBoosted_train")->GetYaxis()->SetTitle("ROC integral boosted");
296  results->GetHist("Overlap")->GetXaxis()->SetTitle("Index of boosted classifier");
297  results->GetHist("Overlap")->GetYaxis()->SetTitle("Overlap integral");
298  }
299 
300  results->Store(new TH1F("SoverBtotal","S/B in reweighted training sample",fBoostNum,0,fBoostNum),"SoverBtotal");
301  results->GetHist("SoverBtotal")->GetYaxis()->SetTitle("S/B (boosted sample)");
302  results->GetHist("SoverBtotal")->GetXaxis()->SetTitle("Index of boosted classifier");
303 
304  results->Store(new TH1F("SeparationGain","SeparationGain",fBoostNum,0,fBoostNum),"SeparationGain");
305  results->GetHist("SeparationGain")->GetYaxis()->SetTitle("SeparationGain");
306  results->GetHist("SeparationGain")->GetXaxis()->SetTitle("Index of boosted classifier");
307 
308 
309 
310  fMonitorTree= new TTree("MonitorBoost","Boost variables");
311  fMonitorTree->Branch("iMethod",&fCurrentMethodIdx,"iMethod/I");
312  fMonitorTree->Branch("boostWeight",&fBoostWeight,"boostWeight/D");
313  fMonitorTree->Branch("errorFraction",&fMethodError,"errorFraction/D");
314  fMonitorBoostedMethod = kTRUE;
315 
316 }
317 
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 
322 {
323  Log() << kDEBUG << "CheckSetup: fBoostType="<<fBoostType << Endl;
324  Log() << kDEBUG << "CheckSetup: fAdaBoostBeta="<<fAdaBoostBeta<<Endl;
325  Log() << kDEBUG << "CheckSetup: fBoostWeight="<<fBoostWeight<<Endl;
326  Log() << kDEBUG << "CheckSetup: fMethodError="<<fMethodError<<Endl;
327  Log() << kDEBUG << "CheckSetup: fBoostNum="<<fBoostNum << Endl;
328  Log() << kDEBUG << "CheckSetup: fRandomSeed=" << fRandomSeed<< Endl;
329  Log() << kDEBUG << "CheckSetup: fTrainSigMVAHist.size()="<<fTrainSigMVAHist.size()<<Endl;
330  Log() << kDEBUG << "CheckSetup: fTestSigMVAHist.size()="<<fTestSigMVAHist.size()<<Endl;
331  Log() << kDEBUG << "CheckSetup: fMonitorBoostedMethod=" << (fMonitorBoostedMethod? "true" : "false") << Endl;
332  Log() << kDEBUG << "CheckSetup: MName=" << fBoostedMethodName << " Title="<< fBoostedMethodTitle<< Endl;
333  Log() << kDEBUG << "CheckSetup: MOptions="<< fBoostedMethodOptions << Endl;
334  Log() << kDEBUG << "CheckSetup: fMonitorTree=" << fMonitorTree <<Endl;
335  Log() << kDEBUG << "CheckSetup: fCurrentMethodIdx=" <<fCurrentMethodIdx << Endl;
336  if (fMethods.size()>0) Log() << kDEBUG << "CheckSetup: fMethods[0]" <<fMethods[0]<<Endl;
337  Log() << kDEBUG << "CheckSetup: fMethodWeight.size()" << fMethodWeight.size() << Endl;
338  if (fMethodWeight.size()>0) Log() << kDEBUG << "CheckSetup: fMethodWeight[0]="<<fMethodWeight[0]<<Endl;
339  Log() << kDEBUG << "CheckSetup: trying to repair things" << Endl;
340 
341 }
342 ////////////////////////////////////////////////////////////////////////////////
343 
345 {
346  TDirectory* methodDir( 0 );
347  TString dirName,dirTitle;
348  Int_t StopCounter=0;
349  Results* results = Data()->GetResults(GetMethodName(), Types::kTraining, GetAnalysisType());
350 
351 
352  InitHistos();
353 
354  if (Data()->GetNTrainingEvents()==0) Log() << kFATAL << "<Train> Data() has zero events" << Endl;
355  Data()->SetCurrentType(Types::kTraining);
356 
357  if (fMethods.size() > 0) fMethods.clear();
358  fMVAvalues->resize(Data()->GetNTrainingEvents(), 0.0);
359 
360  Log() << kINFO << "Training "<< fBoostNum << " " << fBoostedMethodName << " with title " << fBoostedMethodTitle << " Classifiers ... patience please" << Endl;
361  Timer timer( fBoostNum, GetName() );
362 
363  ResetBoostWeights();
364 
365  // clean boosted method options
366  CleanBoostOptions();
367 
368 
369  // remove transformations for individual boosting steps
370  // the transformation of the main method will be rerouted to each of the boost steps
371  Ssiz_t varTrafoStart=fBoostedMethodOptions.Index("~VarTransform=");
372  if (varTrafoStart >0) {
373  Ssiz_t varTrafoEnd =fBoostedMethodOptions.Index(":",varTrafoStart);
374  if (varTrafoEnd<varTrafoStart)
375  varTrafoEnd=fBoostedMethodOptions.Length();
376  fBoostedMethodOptions.Remove(varTrafoStart,varTrafoEnd-varTrafoStart);
377  }
378 
379  //
380  // training and boosting the classifiers
381  for (fCurrentMethodIdx=0;fCurrentMethodIdx<fBoostNum;fCurrentMethodIdx++) {
382  // the first classifier shows the option string output, the rest not
383  if (fCurrentMethodIdx>0) TMVA::MsgLogger::InhibitOutput();
384 
385  IMethod* method = ClassifierFactory::Instance().Create(std::string(fBoostedMethodName),
386  GetJobName(),
387  Form("%s_B%04i", fBoostedMethodTitle.Data(),fCurrentMethodIdx),
388  DataInfo(),
389  fBoostedMethodOptions);
391 
392  // supressing the rest of the classifier output the right way
393  fCurrentMethod = (dynamic_cast<MethodBase*>(method));
394 
395  if (fCurrentMethod==0) {
396  Log() << kFATAL << "uups.. guess the booking of the " << fCurrentMethodIdx << "-th classifier somehow failed" << Endl;
397  return; // hope that makes coverity happy (as if fears I migh use the pointer later on, not knowing that FATAL exits
398  }
399 
400  // set fDataSetManager if MethodCategory (to enable Category to create datasetinfo objects) // DSMTEST
401  if (fCurrentMethod->GetMethodType() == Types::kCategory) { // DSMTEST
402  MethodCategory *methCat = (dynamic_cast<MethodCategory*>(fCurrentMethod)); // DSMTEST
403  if (!methCat) // DSMTEST
404  Log() << kFATAL << "Method with type kCategory cannot be casted to MethodCategory. /MethodBoost" << Endl; // DSMTEST
405  methCat->fDataSetManager = fDataSetManager; // DSMTEST
406  } // DSMTEST
407 
408  fCurrentMethod->SetMsgType(kWARNING);
409  fCurrentMethod->SetupMethod();
410  fCurrentMethod->ParseOptions();
411  // put SetAnalysisType here for the needs of MLP
412  fCurrentMethod->SetAnalysisType( GetAnalysisType() );
413  fCurrentMethod->ProcessSetup();
414  fCurrentMethod->CheckSetup();
415 
416 
417  // reroute transformationhandler
418  fCurrentMethod->RerouteTransformationHandler (&(this->GetTransformationHandler()));
419 
420 
421  // creating the directory of the classifier
422  if (fMonitorBoostedMethod) {
423  methodDir=MethodBaseDir()->GetDirectory(dirName=Form("%s_B%04i",fBoostedMethodName.Data(),fCurrentMethodIdx));
424  if (methodDir==0) {
425  methodDir=BaseDir()->mkdir(dirName,dirTitle=Form("Directory Boosted %s #%04i", fBoostedMethodName.Data(),fCurrentMethodIdx));
426  }
427  fCurrentMethod->SetMethodDir(methodDir);
428  fCurrentMethod->BaseDir()->cd();
429  }
430 
431  // training
432  TMVA::MethodCompositeBase::fMethods.push_back(method);
433  timer.DrawProgressBar( fCurrentMethodIdx );
434  if (fCurrentMethodIdx==0) MonitorBoost(Types::kBoostProcBegin,fCurrentMethodIdx);
435  MonitorBoost(Types::kBeforeTraining,fCurrentMethodIdx);
436  TMVA::MsgLogger::InhibitOutput(); //supressing Logger outside the method
437  if (fBoostType=="Bagging") Bagging(); // you want also to train the first classifier on a bagged sample
438  SingleTrain();
440  fCurrentMethod->WriteMonitoringHistosToFile();
441 
442  // calculate MVA values of current method for all events in training sample
443  // (used later on to get 'misclassified events' etc for the boosting
444  CalcMVAValues();
445 
446  if (fCurrentMethodIdx==0 && fMonitorBoostedMethod) CreateMVAHistorgrams();
447 
448  // get ROC integral and overlap integral for single method on
449  // training sample if fMethodWeightType == "ByROC" or the user
450  // wants detailed monitoring
451 
452  // boosting (reweight training sample)
453  MonitorBoost(Types::kBeforeBoosting,fCurrentMethodIdx);
454  SingleBoost(fCurrentMethod);
455 
456  MonitorBoost(Types::kAfterBoosting,fCurrentMethodIdx);
457  results->GetHist("BoostWeight")->SetBinContent(fCurrentMethodIdx+1,fBoostWeight);
458  results->GetHist("ErrorFraction")->SetBinContent(fCurrentMethodIdx+1,fMethodError);
459 
460  if (fDetailedMonitoring) {
461  fROC_training = GetBoostROCIntegral(kTRUE, Types::kTraining, kTRUE);
462  results->GetHist("ROCIntegral_test")->SetBinContent(fCurrentMethodIdx+1, GetBoostROCIntegral(kTRUE, Types::kTesting));
463  results->GetHist("ROCIntegralBoosted_test")->SetBinContent(fCurrentMethodIdx+1, GetBoostROCIntegral(kFALSE, Types::kTesting));
464  results->GetHist("ROCIntegral_train")->SetBinContent(fCurrentMethodIdx+1, fROC_training);
465  results->GetHist("ROCIntegralBoosted_train")->SetBinContent(fCurrentMethodIdx+1, GetBoostROCIntegral(kFALSE, Types::kTraining));
466  results->GetHist("Overlap")->SetBinContent(fCurrentMethodIdx+1, fOverlap_integral);
467  }
468 
469 
470 
471  fMonitorTree->Fill();
472 
473  // stop boosting if needed when error has reached 0.5
474  // thought of counting a few steps, but it doesn't seem to be necessary
475  Log() << kDEBUG << "AdaBoost (methodErr) err = " << fMethodError << Endl;
476  if (fMethodError > 0.49999) StopCounter++;
477  if (StopCounter > 0 && fBoostType != "Bagging") {
478  timer.DrawProgressBar( fBoostNum );
479  fBoostNum = fCurrentMethodIdx+1;
480  Log() << kINFO << "Error rate has reached 0.5 ("<< fMethodError<<"), boosting process stopped at #" << fBoostNum << " classifier" << Endl;
481  if (fBoostNum < 5)
482  Log() << kINFO << "The classifier might be too strong to boost with Beta = " << fAdaBoostBeta << ", try reducing it." <<Endl;
483  break;
484  }
485  }
486 
487  //as MethodBoost acts not on a private event sample (like MethodBDT does), we need to remember not
488  // to leave "boosted" events to the next classifier in the factory
489 
490  ResetBoostWeights();
491 
492  Timer* timer1= new Timer( fBoostNum, GetName() );
493  // normalizing the weights of the classifiers
494  for (fCurrentMethodIdx=0;fCurrentMethodIdx<fBoostNum;fCurrentMethodIdx++) {
495  // pefroming post-boosting actions
496 
497  timer1->DrawProgressBar( fCurrentMethodIdx );
498 
499  if (fCurrentMethodIdx==fBoostNum) {
500  Log() << kINFO << "Elapsed time: " << timer1->GetElapsedTime()
501  << " " << Endl;
502  }
503 
504  TH1F* tmp = dynamic_cast<TH1F*>( results->GetHist("ClassifierWeight") );
505  if (tmp) tmp->SetBinContent(fCurrentMethodIdx+1,fMethodWeight[fCurrentMethodIdx]);
506 
507  }
508 
509  // Ensure that in case of only 1 boost the method weight equals
510  // 1.0. This avoids unexpected behaviour in case of very bad
511  // classifiers which have fBoostWeight=1 or fMethodError=0.5,
512  // because their weight would be set to zero. This behaviour is
513  // not ok if one boosts just one time.
514  if (fMethods.size()==1) fMethodWeight[0] = 1.0;
515 
516  MonitorBoost(Types::kBoostProcEnd);
517 
518  delete timer1;
519 }
520 
521 ////////////////////////////////////////////////////////////////////////////////
522 
524 {
525  fBoostedMethodOptions=GetOptions();
526 }
527 
528 ////////////////////////////////////////////////////////////////////////////////
529 
531 {
532  if (fBoostNum <=0) Log() << kFATAL << "CreateHistorgrams called before fBoostNum is initialized" << Endl;
533  // calculating histograms boundries and creating histograms..
534  // nrms = number of rms around the average to use for outline (of the 0 classifier)
535  Double_t meanS, meanB, rmsS, rmsB, xmin, xmax, nrms = 10;
536  Int_t signalClass = 0;
537  if (DataInfo().GetClassInfo("Signal") != 0) {
538  signalClass = DataInfo().GetClassInfo("Signal")->GetNumber();
539  }
540  gTools().ComputeStat( GetEventCollection( Types::kMaxTreeType ), fMVAvalues,
541  meanS, meanB, rmsS, rmsB, xmin, xmax, signalClass );
542 
544  xmin = TMath::Max( TMath::Min(meanS - nrms*rmsS, meanB - nrms*rmsB ), xmin );
545  xmax = TMath::Min( TMath::Max(meanS + nrms*rmsS, meanB + nrms*rmsB ), xmax ) + 0.00001;
546 
547  // creating all the historgrams
548  for (UInt_t imtd=0; imtd<fBoostNum; imtd++) {
549  fTrainSigMVAHist .push_back( new TH1F( Form("MVA_Train_S_%04i",imtd), "MVA_Train_S", fNbins, xmin, xmax ) );
550  fTrainBgdMVAHist .push_back( new TH1F( Form("MVA_Train_B%04i", imtd), "MVA_Train_B", fNbins, xmin, xmax ) );
551  fBTrainSigMVAHist.push_back( new TH1F( Form("MVA_BTrain_S%04i",imtd), "MVA_BoostedTrain_S", fNbins, xmin, xmax ) );
552  fBTrainBgdMVAHist.push_back( new TH1F( Form("MVA_BTrain_B%04i",imtd), "MVA_BoostedTrain_B", fNbins, xmin, xmax ) );
553  fTestSigMVAHist .push_back( new TH1F( Form("MVA_Test_S%04i", imtd), "MVA_Test_S", fNbins, xmin, xmax ) );
554  fTestBgdMVAHist .push_back( new TH1F( Form("MVA_Test_B%04i", imtd), "MVA_Test_B", fNbins, xmin, xmax ) );
555  }
556 }
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// resetting back the boosted weights of the events to 1
560 
562 {
563  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
564  const Event *ev = Data()->GetEvent(ievt);
565  ev->SetBoostWeight( 1.0 );
566  }
567 }
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 
572 {
573  TDirectory* dir=0;
574  if (fMonitorBoostedMethod) {
575  for (UInt_t imtd=0;imtd<fBoostNum;imtd++) {
576 
577  //writing the histograms in the specific classifier's directory
578  MethodBase* m = dynamic_cast<MethodBase*>(fMethods[imtd]);
579  if (!m) continue;
580  dir = m->BaseDir();
581  dir->cd();
582  fTrainSigMVAHist[imtd]->SetDirectory(dir);
583  fTrainSigMVAHist[imtd]->Write();
584  fTrainBgdMVAHist[imtd]->SetDirectory(dir);
585  fTrainBgdMVAHist[imtd]->Write();
586  fBTrainSigMVAHist[imtd]->SetDirectory(dir);
587  fBTrainSigMVAHist[imtd]->Write();
588  fBTrainBgdMVAHist[imtd]->SetDirectory(dir);
589  fBTrainBgdMVAHist[imtd]->Write();
590  }
591  }
592 
593  // going back to the original folder
594  BaseDir()->cd();
595 
596  fMonitorTree->Write();
597 }
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 
602 {
604  if (fMonitorBoostedMethod) {
605  UInt_t nloop = fTestSigMVAHist.size();
606  if (fMethods.size()<nloop) nloop = fMethods.size();
607  //running over all the events and populating the test MVA histograms
608  Data()->SetCurrentType(Types::kTesting);
609  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
610  const Event* ev = GetEvent(ievt);
611  Float_t w = ev->GetWeight();
612  if (DataInfo().IsSignal(ev)) {
613  for (UInt_t imtd=0; imtd<nloop; imtd++) {
614  fTestSigMVAHist[imtd]->Fill(fMethods[imtd]->GetMvaValue(),w);
615  }
616  }
617  else {
618  for (UInt_t imtd=0; imtd<nloop; imtd++) {
619  fTestBgdMVAHist[imtd]->Fill(fMethods[imtd]->GetMvaValue(),w);
620  }
621  }
622  }
623  Data()->SetCurrentType(Types::kTraining);
624  }
625 }
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 
630 {
632  if (treetype==Types::kTraining) return;
633  UInt_t nloop = fTestSigMVAHist.size();
634  if (fMethods.size()<nloop) nloop = fMethods.size();
635  if (fMonitorBoostedMethod) {
636  TDirectory* dir=0;
637  for (UInt_t imtd=0;imtd<nloop;imtd++) {
638  //writing the histograms in the specific classifier's directory
639  MethodBase* mva = dynamic_cast<MethodBase*>(fMethods[imtd]);
640  if (!mva) continue;
641  dir = mva->BaseDir();
642  if (dir==0) continue;
643  dir->cd();
644  fTestSigMVAHist[imtd]->SetDirectory(dir);
645  fTestSigMVAHist[imtd]->Write();
646  fTestBgdMVAHist[imtd]->SetDirectory(dir);
647  fTestBgdMVAHist[imtd]->Write();
648  }
649  }
650 }
651 
652 ////////////////////////////////////////////////////////////////////////////////
653 /// process user options
654 
656 {
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// initialization
661 
663 {
664  Data()->SetCurrentType(Types::kTraining);
665  MethodBase* meth = dynamic_cast<MethodBase*>(GetLastMethod());
666  if (meth) meth->TrainMethod();
667 }
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 /// find the CUT on the individual MVA that defines an event as
671 /// correct or misclassified (to be used in the boosting process)
672 
674 {
675  if (!method || method->GetMethodType() == Types::kDT ){ return;}
676 
677  // creating a fine histograms containing the error rate
678  const Int_t nBins=10001;
679  Double_t minMVA=150000;
680  Double_t maxMVA=-150000;
681  for (Long64_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
682  GetEvent(ievt);
683  Double_t val=method->GetMvaValue();
684  //Helge .. I think one could very well use fMVAValues for that ... -->to do
685  if (val>maxMVA) maxMVA=val;
686  if (val<minMVA) minMVA=val;
687  }
688  maxMVA = maxMVA+(maxMVA-minMVA)/nBins;
689 
690  Double_t sum = 0.;
691 
692  TH1D *mvaS = new TH1D(Form("MVAS_%d",fCurrentMethodIdx) ,"",nBins,minMVA,maxMVA);
693  TH1D *mvaB = new TH1D(Form("MVAB_%d",fCurrentMethodIdx) ,"",nBins,minMVA,maxMVA);
694  TH1D *mvaSC = new TH1D(Form("MVASC_%d",fCurrentMethodIdx),"",nBins,minMVA,maxMVA);
695  TH1D *mvaBC = new TH1D(Form("MVABC_%d",fCurrentMethodIdx),"",nBins,minMVA,maxMVA);
696 
697 
698  Results* results = Data()->GetResults(GetMethodName(), Types::kTraining, GetAnalysisType());
699  if (fDetailedMonitoring){
700  results->Store(mvaS, Form("MVAS_%d",fCurrentMethodIdx));
701  results->Store(mvaB, Form("MVAB_%d",fCurrentMethodIdx));
702  results->Store(mvaSC,Form("MVASC_%d",fCurrentMethodIdx));
703  results->Store(mvaBC,Form("MVABC_%d",fCurrentMethodIdx));
704  }
705 
706  for (Long64_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
707 
708  Double_t weight = GetEvent(ievt)->GetWeight();
709  Double_t mvaVal=method->GetMvaValue();
710  sum +=weight;
711  if (DataInfo().IsSignal(GetEvent(ievt))){
712  mvaS->Fill(mvaVal,weight);
713  }else {
714  mvaB->Fill(mvaVal,weight);
715  }
716  }
717  SeparationBase *sepGain;
718 
719 
720  // Boosting should use Miscalssification not Gini Index (changed, Helge 31.5.2013)
721  // ACHTUNG !! mit "Misclassification" geht es NUR wenn man die Signal zu Background bei jedem Boost schritt
722  // wieder hinbiegt. Es gibt aber komischerweise bessere Ergebnisse (genau wie bei BDT auch schon beobachtet) wenn
723  // man GiniIndex benutzt und akzeptiert dass jedes andere mal KEIN vernuenftiger Cut gefunden wird - d.h. der
724  // Cut liegt dann ausserhalb der MVA value range, alle events sind als Bkg classifiziert und dann wird entpsrehcend
725  // des Boost algorithmus 'automitisch' etwas renormiert .. sodass im naechsten Schritt dann wieder was vernuenftiges
726  // rauskommt. Komisch .. dass DAS richtig sein soll ??
727 
728  // SeparationBase *sepGain2 = new MisClassificationError();
729  //sepGain = new MisClassificationError();
730  sepGain = new GiniIndex();
731  //sepGain = new CrossEntropy();
732 
733  Double_t sTot = mvaS->GetSum();
734  Double_t bTot = mvaB->GetSum();
735 
736  mvaSC->SetBinContent(1,mvaS->GetBinContent(1));
737  mvaBC->SetBinContent(1,mvaB->GetBinContent(1));
738  Double_t sSel=0;
739  Double_t bSel=0;
740  Double_t separationGain=sepGain->GetSeparationGain(sSel,bSel,sTot,bTot);
741  Double_t mvaCut=mvaSC->GetBinLowEdge(1);
742  Double_t sSelCut=sSel;
743  Double_t bSelCut=bSel;
744  // std::cout << "minMVA =" << minMVA << " maxMVA = " << maxMVA << " width = " << mvaSC->GetBinWidth(1) << std::endl;
745 
746  // for (Int_t ibin=1;ibin<=nBins;ibin++) std::cout << " cutvalues[" << ibin<<"]="<<mvaSC->GetBinLowEdge(ibin) << " " << mvaSC->GetBinCenter(ibin) << std::endl;
747  Double_t mvaCutOrientation=1; // 1 if mva > mvaCut --> Signal and -1 if mva < mvaCut (i.e. mva*-1 > mvaCut*-1) --> Signal
748  for (Int_t ibin=1;ibin<=nBins;ibin++){
749  mvaSC->SetBinContent(ibin,mvaS->GetBinContent(ibin)+mvaSC->GetBinContent(ibin-1));
750  mvaBC->SetBinContent(ibin,mvaB->GetBinContent(ibin)+mvaBC->GetBinContent(ibin-1));
751 
752  sSel=mvaSC->GetBinContent(ibin);
753  bSel=mvaBC->GetBinContent(ibin);
754 
755  // if (ibin==nBins){
756  // std::cout << "Last bin s="<< sSel <<" b="<<bSel << " s="<< sTot-sSel <<" b="<<bTot-bSel << endl;
757  // }
758 
759  if (separationGain < sepGain->GetSeparationGain(sSel,bSel,sTot,bTot)
760  // && (mvaSC->GetBinCenter(ibin) >0 || (fCurrentMethodIdx+1)%2 )
761  ){
762  separationGain = sepGain->GetSeparationGain(sSel,bSel,sTot,bTot);
763  // mvaCut=mvaSC->GetBinCenter(ibin);
764  mvaCut=mvaSC->GetBinLowEdge(ibin+1);
765  // if (sSel/bSel > (sTot-sSel)/(bTot-bSel)) mvaCutOrientation=-1;
766  if (sSel*(bTot-bSel) > (sTot-sSel)*bSel) mvaCutOrientation=-1;
767  else mvaCutOrientation=1;
768  sSelCut=sSel;
769  bSelCut=bSel;
770  // std::cout << "new cut at " << mvaCut << "with s="<<sTot-sSel << " b="<<bTot-bSel << std::endl;
771  }
772  /*
773  Double_t ori;
774  if (sSel/bSel > (sTot-sSel)/(bTot-bSel)) ori=-1;
775  else ori=1;
776  std::cout << ibin << " mvacut="<<mvaCut
777  << " sTot=" << sTot
778  << " bTot=" << bTot
779  << " sSel=" << sSel
780  << " bSel=" << bSel
781  << " s/b(1)=" << sSel/bSel
782  << " s/b(2)=" << (sTot-sSel)/(bTot-bSel)
783  << " sepGain="<<sepGain->GetSeparationGain(sSel,bSel,sTot,bTot)
784  << " sepGain2="<<sepGain2->GetSeparationGain(sSel,bSel,sTot,bTot)
785  << " " <<ori
786  << std::endl;
787  */
788 
789  }
790 
791  if (0){
792  double parentIndex=sepGain->GetSeparationIndex(sTot,bTot);
793  double leftIndex =sepGain->GetSeparationIndex(sSelCut,bSelCut);
794  double rightIndex =sepGain->GetSeparationIndex(sTot-sSelCut,bTot-bSelCut);
795  std::cout
796  << " sTot=" << sTot
797  << " bTot=" << bTot
798  << " s="<<sSelCut
799  << " b="<<bSelCut
800  << " s2="<<(sTot-sSelCut)
801  << " b2="<<(bTot-bSelCut)
802  << " s/b(1)=" << sSelCut/bSelCut
803  << " s/b(2)=" << (sTot-sSelCut)/(bTot-bSelCut)
804  << " index before cut=" << parentIndex
805  << " after: left=" << leftIndex
806  << " after: right=" << rightIndex
807  << " sepGain=" << parentIndex-( (sSelCut+bSelCut) * leftIndex + (sTot-sSelCut+bTot-bSelCut) * rightIndex )/(sTot+bTot)
808  << " sepGain="<<separationGain
809  << " sepGain="<<sepGain->GetSeparationGain(sSelCut,bSelCut,sTot,bTot)
810  << " cut=" << mvaCut
811  << " idx="<<fCurrentMethodIdx
812  << " cutOrientation="<<mvaCutOrientation
813  << std::endl;
814  }
815  method->SetSignalReferenceCut(mvaCut);
816  method->SetSignalReferenceCutOrientation(mvaCutOrientation);
817 
818  results->GetHist("SeparationGain")->SetBinContent(fCurrentMethodIdx+1,separationGain);
819 
820 
821  Log() << kDEBUG << "(old step) Setting method cut to " <<method->GetSignalReferenceCut()<< Endl;
822 
823  // mvaS ->Delete();
824  // mvaB ->Delete();
825  // mvaSC->Delete();
826  // mvaBC->Delete();
827 }
828 
829 ////////////////////////////////////////////////////////////////////////////////
830 
832 {
833  Double_t returnVal=-1;
834 
835 
836  if (fBoostType=="AdaBoost") returnVal = this->AdaBoost (method,1);
837  else if (fBoostType=="RealAdaBoost") returnVal = this->AdaBoost (method,0);
838  else if (fBoostType=="Bagging") returnVal = this->Bagging ();
839  else{
840  Log() << kFATAL << "<Boost> unknown boost option " << fBoostType<< " called" << Endl;
841  }
842  fMethodWeight.push_back(returnVal);
843  return returnVal;
844 }
845 ////////////////////////////////////////////////////////////////////////////////
846 /// the standard (discrete or real) AdaBoost algorithm
847 
849 {
850  if (!method) {
851  Log() << kWARNING << " AdaBoost called without classifier reference - needed for calulating AdaBoost " << Endl;
852  return 0;
853  }
854 
855  Float_t w,v; Bool_t sig=kTRUE;
856  Double_t sumAll=0, sumWrong=0;
857  Bool_t* WrongDetection=new Bool_t[GetNEvents()];
858  QuickMVAProbEstimator *MVAProb=NULL;
859 
860  if (discreteAdaBoost) {
861  FindMVACut(method);
862  Log() << kDEBUG << " individual mva cut value = " << method->GetSignalReferenceCut() << Endl;
863  } else {
864  MVAProb=new TMVA::QuickMVAProbEstimator();
865  // the RealAdaBoost does use a simple "yes (signal)" or "no (background)"
866  // answer from your single MVA, but a "signal probability" instead (in the BDT case,
867  // that would be the 'purity' in the leaf node. For some MLP parameter, the MVA output
868  // can also interpreted as a probability, but here I try a genera aproach to get this
869  // probability from the MVA distributions...
870 
871  for (Long64_t evt=0; evt<GetNEvents(); evt++) {
872  const Event* ev = Data()->GetEvent(evt);
873  MVAProb->AddEvent(fMVAvalues->at(evt),ev->GetWeight(),ev->GetClass());
874  }
875  }
876 
877 
878  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) WrongDetection[ievt]=kTRUE;
879 
880  // finding the wrong events and calculating their total weights
881  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
882  const Event* ev = GetEvent(ievt);
883  sig=DataInfo().IsSignal(ev);
884  v = fMVAvalues->at(ievt);
885  w = ev->GetWeight();
886  sumAll += w;
887  if (fMonitorBoostedMethod) {
888  if (sig) {
889  fBTrainSigMVAHist[fCurrentMethodIdx]->Fill(v,w);
890  fTrainSigMVAHist[fCurrentMethodIdx]->Fill(v,ev->GetOriginalWeight());
891  }
892  else {
893  fBTrainBgdMVAHist[fCurrentMethodIdx]->Fill(v,w);
894  fTrainBgdMVAHist[fCurrentMethodIdx]->Fill(v,ev->GetOriginalWeight());
895  }
896  }
897 
898  if (discreteAdaBoost){
899  if (sig == method->IsSignalLike(fMVAvalues->at(ievt))){
900  WrongDetection[ievt]=kFALSE;
901  }else{
902  WrongDetection[ievt]=kTRUE;
903  sumWrong+=w;
904  }
905  }else{
906  Double_t mvaProb = MVAProb->GetMVAProbAt((Float_t)fMVAvalues->at(ievt));
907  mvaProb = 2*(mvaProb-0.5);
908  Int_t trueType;
909  if (DataInfo().IsSignal(ev)) trueType = 1;
910  else trueType = -1;
911  sumWrong+= w*trueType*mvaProb;
912  }
913  }
914 
915  fMethodError=sumWrong/sumAll;
916 
917  // calculating the fMethodError and the boostWeight out of it uses the formula
918  // w = ((1-err)/err)^beta
919 
920  Double_t boostWeight=0;
921 
922  if (fMethodError == 0) { //no misclassification made.. perfect, no boost ;)
923  Log() << kWARNING << "Your classifier worked perfectly on the training sample --> serious overtraining expected and no boosting done " << Endl;
924  }else{
925 
926  if (discreteAdaBoost)
927  boostWeight = TMath::Log((1.-fMethodError)/fMethodError)*fAdaBoostBeta;
928  else
929  boostWeight = TMath::Log((1.+fMethodError)/(1-fMethodError))*fAdaBoostBeta;
930 
931 
932  // std::cout << "boostweight = " << boostWeight << std::endl;
933 
934  // ADA boosting, rescaling the weight of the wrong events according to the error level
935  // over the entire test sample rescaling all the weights to have the same sum, but without
936  // touching the original weights (changing only the boosted weight of all the events)
937  // first reweight
938 
939  Double_t newSum=0., oldSum=0.;
940 
941 
942  Double_t boostfactor = TMath::Exp(boostWeight);
943 
944 
945  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
946  const Event* ev = Data()->GetEvent(ievt);
947  oldSum += ev->GetWeight();
948  if (discreteAdaBoost){
949  // events are classified as Signal OR background .. right or wrong
950  if (WrongDetection[ievt] && boostWeight != 0) {
951  if (ev->GetWeight() > 0) ev->ScaleBoostWeight(boostfactor);
952  else ev->ScaleBoostWeight(1./boostfactor);
953  }
954  // if (ievt<30) std::cout<<ievt<<" var0="<<ev->GetValue(0)<<" var1="<<ev->GetValue(1)<<" weight="<<ev->GetWeight() << " boostby:"<<boostfactor<<std::endl;
955 
956  }else{
957  // events are classified by their probability of being signal or background
958  // (eventually you should write this one - i.e. re-use the MVA value that were already
959  // calcualted and stroed.. however ,for the moement ..
960  Double_t mvaProb = MVAProb->GetMVAProbAt((Float_t)fMVAvalues->at(ievt));
961  mvaProb = 2*(mvaProb-0.5);
962  // mvaProb = (1-mvaProb);
963 
964  Int_t trueType=1;
965  if (DataInfo().IsSignal(ev)) trueType = 1;
966  else trueType = -1;
967 
968  boostfactor = TMath::Exp(-1*boostWeight*trueType*mvaProb);
969  if (ev->GetWeight() > 0) ev->ScaleBoostWeight(boostfactor);
970  else ev->ScaleBoostWeight(1./boostfactor);
971 
972  }
973  newSum += ev->GetWeight();
974  }
975 
976  Double_t normWeight = oldSum/newSum;
977  // next normalize the weights
978  Double_t normSig=0, normBkg=0;
979  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
980  const Event* ev = Data()->GetEvent(ievt);
981  ev->ScaleBoostWeight(normWeight);
982  if (ev->GetClass()) normSig+=ev->GetWeight();
983  else normBkg+=ev->GetWeight();
984  }
985 
986  Results* results = Data()->GetResults(GetMethodName(), Types::kTraining, GetAnalysisType());
987  results->GetHist("SoverBtotal")->SetBinContent(fCurrentMethodIdx+1, normSig/normBkg);
988 
989  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
990  const Event* ev = Data()->GetEvent(ievt);
991 
992  if (ev->GetClass()) ev->ScaleBoostWeight(oldSum/normSig/2);
993  else ev->ScaleBoostWeight(oldSum/normBkg/2);
994  }
995  }
996 
997  delete[] WrongDetection;
998  if (MVAProb) delete MVAProb;
999 
1000  fBoostWeight = boostWeight; // used ONLY for the monitoring tree
1001 
1002  return boostWeight;
1003 }
1004 
1005 
1006 ////////////////////////////////////////////////////////////////////////////////
1007 /// Bagging or Bootstrap boosting, gives new random poisson weight for every event
1008 
1010 {
1011  TRandom3 *trandom = new TRandom3(fRandomSeed+fMethods.size());
1012  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1013  const Event* ev = Data()->GetEvent(ievt);
1014  ev->SetBoostWeight(trandom->PoissonD(fBaggedSampleFraction));
1015  }
1016  fBoostWeight = 1; // used ONLY for the monitoring tree
1017  return 1.;
1018 }
1019 
1020 
1021 ////////////////////////////////////////////////////////////////////////////////
1022 /// Get help message text
1023 ///
1024 /// typical length of text line:
1025 /// "|--------------------------------------------------------------|"
1026 
1028 {
1029  Log() << Endl;
1030  Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
1031  Log() << Endl;
1032  Log() << "This method combines several classifier of one species in a "<<Endl;
1033  Log() << "single multivariate quantity via the boost algorithm." << Endl;
1034  Log() << "the output is a weighted sum over all individual classifiers" <<Endl;
1035  Log() << "By default, the AdaBoost method is employed, which gives " << Endl;
1036  Log() << "events that were misclassified in the previous tree a larger " << Endl;
1037  Log() << "weight in the training of the following classifier."<<Endl;
1038  Log() << "Optionally, Bagged boosting can also be applied." << Endl;
1039  Log() << Endl;
1040  Log() << gTools().Color("bold") << "--- Performance tuning via configuration options:" << gTools().Color("reset") << Endl;
1041  Log() << Endl;
1042  Log() << "The most important parameter in the configuration is the "<<Endl;
1043  Log() << "number of boosts applied (Boost_Num) and the choice of boosting"<<Endl;
1044  Log() << "(Boost_Type), which can be set to either AdaBoost or Bagging." << Endl;
1045  Log() << "AdaBoosting: The most important parameters in this configuration" <<Endl;
1046  Log() << "is the beta parameter (Boost_AdaBoostBeta) " << Endl;
1047  Log() << "When boosting a linear classifier, it is sometimes advantageous"<<Endl;
1048  Log() << "to transform the MVA output non-linearly. The following options" <<Endl;
1049  Log() << "are available: step, log, and minmax, the default is no transform."<<Endl;
1050  Log() <<Endl;
1051  Log() << "Some classifiers are hard to boost and do not improve much in"<<Endl;
1052  Log() << "their performance by boosting them, some even slightly deteriorate"<< Endl;
1053  Log() << "due to the boosting." <<Endl;
1054  Log() << "The booking of the boost method is special since it requires"<<Endl;
1055  Log() << "the booing of the method to be boosted and the boost itself."<<Endl;
1056  Log() << "This is solved by booking the method to be boosted and to add"<<Endl;
1057  Log() << "all Boost parameters, which all begin with \"Boost_\" to the"<<Endl;
1058  Log() << "options string. The factory separates the options and initiates"<<Endl;
1059  Log() << "the boost process. The TMVA macro directory contains the example"<<Endl;
1060  Log() << "macro \"Boost.C\"" <<Endl;
1061 }
1062 
1063 ////////////////////////////////////////////////////////////////////////////////
1064 
1066 {
1067  return 0;
1068 }
1069 
1070 ////////////////////////////////////////////////////////////////////////////////
1071 /// return boosted MVA response
1072 
1074 {
1075  Double_t mvaValue = 0;
1076  Double_t norm = 0;
1077  Double_t epsilon = TMath::Exp(-1.);
1078  //Double_t fact = TMath::Exp(-1.)+TMath::Exp(1.);
1079  for (UInt_t i=0;i< fMethods.size(); i++){
1080  MethodBase* m = dynamic_cast<MethodBase*>(fMethods[i]);
1081  if (m==0) continue;
1082  Double_t val = fTmpEvent ? m->GetMvaValue(fTmpEvent) : m->GetMvaValue();
1083  Double_t sigcut = m->GetSignalReferenceCut();
1084 
1085  // default is no transform
1086  if (fTransformString == "linear"){
1087 
1088  }
1089  else if (fTransformString == "log"){
1090  if (val < sigcut) val = sigcut;
1091 
1092  val = TMath::Log((val-sigcut)+epsilon);
1093  }
1094  else if (fTransformString == "step" ){
1095  if (m->IsSignalLike(val)) val = 1.;
1096  else val = -1.;
1097  }
1098  else if (fTransformString == "gauss"){
1099  val = TMath::Gaus((val-sigcut),1);
1100  }
1101  else {
1102  Log() << kFATAL << "error unknown transformation " << fTransformString<<Endl;
1103  }
1104  mvaValue+=val*fMethodWeight[i];
1105  norm +=fMethodWeight[i];
1106  // std::cout << "mva("<<i<<") = "<<val<<" " << valx<< " " << mvaValue<<" and sigcut="<<sigcut << std::endl;
1107  }
1108  mvaValue/=norm;
1109  // cannot determine error
1110  NoErrorCalc(err, errUpper);
1111 
1112  return mvaValue;
1113 }
1114 
1115 ////////////////////////////////////////////////////////////////////////////////
1116 /// Calculate the ROC integral of a single classifier or even the
1117 /// whole boosted classifier. The tree type (training or testing
1118 /// sample) is specified by 'eTT'.
1119 ///
1120 /// If tree type kTraining is set, the original training sample is
1121 /// used to compute the ROC integral (original weights).
1122 ///
1123 /// - singleMethod - if kTRUE, return ROC integral of single (last
1124 /// trained) classifier; if kFALSE, return ROC
1125 /// integral of full classifier
1126 ///
1127 /// - eTT - tree type (Types::kTraining / Types::kTesting)
1128 ///
1129 /// - CalcOverlapIntergral - if kTRUE, the overlap integral of the
1130 /// signal/background MVA distributions
1131 /// is calculated and stored in
1132 /// 'fOverlap_integral'
1133 
1135 {
1136  // set data sample training / testing
1137  Data()->SetCurrentType(eTT);
1138 
1139  MethodBase* method = singleMethod ? dynamic_cast<MethodBase*>(fMethods.back()) : 0; // ToDo CoVerity flags this line as there is no prtection against a zero-pointer delivered by dynamic_cast
1140  // to make CoVerity happy (although, OF COURSE, the last method in the commitee
1141  // has to be also of type MethodBase as ANY method is... hence the dynamic_cast
1142  // will never by "zero" ...
1143  if (singleMethod && !method) {
1144  Log() << kFATAL << " What do you do? Your method:"
1145  << fMethods.back()->GetName()
1146  << " seems not to be a propper TMVA method"
1147  << Endl;
1148  std::exit(1);
1149  }
1150  Double_t err = 0.0;
1151 
1152  // temporary renormalize the method weights in case of evaluation
1153  // of full classifier.
1154  // save the old normalization of the methods
1155  std::vector<Double_t> OldMethodWeight(fMethodWeight);
1156  if (!singleMethod) {
1157  // calculate sum of weights of all methods
1158  Double_t AllMethodsWeight = 0;
1159  for (UInt_t i=0; i<=fCurrentMethodIdx; i++)
1160  AllMethodsWeight += fMethodWeight.at(i);
1161  // normalize the weights of the classifiers
1162  if (AllMethodsWeight != 0.0) {
1163  for (UInt_t i=0; i<=fCurrentMethodIdx; i++)
1164  fMethodWeight[i] /= AllMethodsWeight;
1165  }
1166  }
1167 
1168  // calculate MVA values
1169  Double_t meanS, meanB, rmsS, rmsB, xmin, xmax, nrms = 10;
1170  std::vector <Float_t>* mvaRes;
1171  if (singleMethod && eTT==Types::kTraining)
1172  mvaRes = fMVAvalues; // values already calculated
1173  else {
1174  mvaRes = new std::vector <Float_t>(GetNEvents());
1175  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1176  GetEvent(ievt);
1177  (*mvaRes)[ievt] = singleMethod ? method->GetMvaValue(&err) : GetMvaValue(&err);
1178  }
1179  }
1180 
1181  // restore the method weights
1182  if (!singleMethod)
1183  fMethodWeight = OldMethodWeight;
1184 
1185  // now create histograms for calculation of the ROC integral
1186  Int_t signalClass = 0;
1187  if (DataInfo().GetClassInfo("Signal") != 0) {
1188  signalClass = DataInfo().GetClassInfo("Signal")->GetNumber();
1189  }
1190  gTools().ComputeStat( GetEventCollection(eTT), mvaRes,
1191  meanS, meanB, rmsS, rmsB, xmin, xmax, signalClass );
1192 
1194  xmin = TMath::Max( TMath::Min(meanS - nrms*rmsS, meanB - nrms*rmsB ), xmin );
1195  xmax = TMath::Min( TMath::Max(meanS + nrms*rmsS, meanB + nrms*rmsB ), xmax ) + 0.0001;
1196 
1197  // calculate ROC integral
1198  TH1* mva_s = new TH1F( "MVA_S", "MVA_S", fNbins, xmin, xmax );
1199  TH1* mva_b = new TH1F( "MVA_B", "MVA_B", fNbins, xmin, xmax );
1200  TH1 *mva_s_overlap=0, *mva_b_overlap=0;
1201  if (CalcOverlapIntergral) {
1202  mva_s_overlap = new TH1F( "MVA_S_OVERLAP", "MVA_S_OVERLAP", fNbins, xmin, xmax );
1203  mva_b_overlap = new TH1F( "MVA_B_OVERLAP", "MVA_B_OVERLAP", fNbins, xmin, xmax );
1204  }
1205  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1206  const Event* ev = GetEvent(ievt);
1207  Float_t w = (eTT==Types::kTesting ? ev->GetWeight() : ev->GetOriginalWeight());
1208  if (DataInfo().IsSignal(ev)) mva_s->Fill( (*mvaRes)[ievt], w );
1209  else mva_b->Fill( (*mvaRes)[ievt], w );
1210 
1211  if (CalcOverlapIntergral) {
1212  Float_t w_ov = ev->GetWeight();
1213  if (DataInfo().IsSignal(ev))
1214  mva_s_overlap->Fill( (*mvaRes)[ievt], w_ov );
1215  else
1216  mva_b_overlap->Fill( (*mvaRes)[ievt], w_ov );
1217  }
1218  }
1219  gTools().NormHist( mva_s );
1220  gTools().NormHist( mva_b );
1221  PDF *fS = new PDF( "PDF Sig", mva_s, PDF::kSpline2 );
1222  PDF *fB = new PDF( "PDF Bkg", mva_b, PDF::kSpline2 );
1223 
1224  // calculate ROC integral from fS, fB
1225  Double_t ROC = MethodBase::GetROCIntegral(fS, fB);
1226 
1227  // calculate overlap integral
1228  if (CalcOverlapIntergral) {
1229  gTools().NormHist( mva_s_overlap );
1230  gTools().NormHist( mva_b_overlap );
1231 
1232  fOverlap_integral = 0.0;
1233  for (Int_t bin=1; bin<=mva_s_overlap->GetNbinsX(); bin++){
1234  Double_t bc_s = mva_s_overlap->GetBinContent(bin);
1235  Double_t bc_b = mva_b_overlap->GetBinContent(bin);
1236  if (bc_s > 0.0 && bc_b > 0.0)
1237  fOverlap_integral += TMath::Min(bc_s, bc_b);
1238  }
1239 
1240  delete mva_s_overlap;
1241  delete mva_b_overlap;
1242  }
1243 
1244  delete mva_s;
1245  delete mva_b;
1246  delete fS;
1247  delete fB;
1248  if (!(singleMethod && eTT==Types::kTraining)) delete mvaRes;
1249 
1250  Data()->SetCurrentType(Types::kTraining);
1251 
1252  return ROC;
1253 }
1254 
1256 {
1257  // Calculate MVA values of current method fMethods.back() on
1258  // training sample
1259 
1260  Data()->SetCurrentType(Types::kTraining);
1261  MethodBase* method = dynamic_cast<MethodBase*>(fMethods.back());
1262  if (!method) {
1263  Log() << kFATAL << "dynamic cast to MethodBase* failed" <<Endl;
1264  return;
1265  }
1266  // calculate MVA values
1267  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1268  GetEvent(ievt);
1269  fMVAvalues->at(ievt) = method->GetMvaValue();
1270  }
1271 
1272  // fill cumulative mva distribution
1273 
1274 
1275 }
1276 
1277 
1278 ////////////////////////////////////////////////////////////////////////////////
1279 /// fill various monitoring histograms from information of the individual classifiers that
1280 /// have been boosted.
1281 /// of course.... this depends very much on the individual classifiers, and so far, only for
1282 /// Decision Trees, this monitoring is actually implemented
1283 
1285 {
1286  Results* results = Data()->GetResults(GetMethodName(), Types::kTraining, GetAnalysisType());
1287 
1288  if (GetCurrentMethod(methodIndex)->GetMethodType() == TMVA::Types::kDT) {
1289  TMVA::MethodDT* currentDT=dynamic_cast<TMVA::MethodDT*>(GetCurrentMethod(methodIndex));
1290  if (currentDT){
1291  if (stage == Types::kBoostProcBegin){
1292  results->Store(new TH1I("NodesBeforePruning","nodes before pruning",this->GetBoostNum(),0,this->GetBoostNum()),"NodesBeforePruning");
1293  results->Store(new TH1I("NodesAfterPruning","nodes after pruning",this->GetBoostNum(),0,this->GetBoostNum()),"NodesAfterPruning");
1294  }
1295 
1296  if (stage == Types::kBeforeTraining){
1297  }
1298  else if (stage == Types::kBeforeBoosting){
1299  results->GetHist("NodesBeforePruning")->SetBinContent(methodIndex+1,currentDT->GetNNodesBeforePruning());
1300  results->GetHist("NodesAfterPruning")->SetBinContent(methodIndex+1,currentDT->GetNNodes());
1301  }
1302  else if (stage == Types::kAfterBoosting){
1303 
1304  }
1305  else if (stage != Types::kBoostProcEnd){
1306  Log() << kINFO << "<Train> average number of nodes before/after pruning : "
1307  << results->GetHist("NodesBeforePruning")->GetMean() << " / "
1308  << results->GetHist("NodesAfterPruning")->GetMean()
1309  << Endl;
1310  }
1311  }
1312 
1313  }else if (GetCurrentMethod(methodIndex)->GetMethodType() == TMVA::Types::kFisher) {
1314  if (stage == Types::kAfterBoosting){
1316  }
1317  }else{
1318  if (methodIndex < 3){
1319  Log() << kINFO << "No detailed boost monitoring for "
1320  << GetCurrentMethod(methodIndex)->GetMethodName()
1321  << " yet available " << Endl;
1322  }
1323  }
1324 
1325  //boosting plots universal for all classifiers 'typically for debug purposes only as they are not general enough'
1326 
1327  if (stage == Types::kBeforeBoosting){
1328  // if you want to display the weighted events for 2D case at each boost step:
1329  if (fDetailedMonitoring){
1330  // the following code is useful only for 2D examples - mainly illustration for debug/educational purposes:
1331  if (DataInfo().GetNVariables() == 2) {
1332  results->Store(new TH2F(Form("EventDistSig_%d",methodIndex),Form("EventDistSig_%d",methodIndex),100,0,7,100,0,7));
1333  results->GetHist(Form("EventDistSig_%d",methodIndex))->SetMarkerColor(4);
1334  results->Store(new TH2F(Form("EventDistBkg_%d",methodIndex),Form("EventDistBkg_%d",methodIndex),100,0,7,100,0,7));
1335  results->GetHist(Form("EventDistBkg_%d",methodIndex))->SetMarkerColor(2);
1336 
1337  Data()->SetCurrentType(Types::kTraining);
1338  for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
1339  const Event* ev = GetEvent(ievt);
1340  Float_t w = ev->GetWeight();
1341  Float_t v0= ev->GetValue(0);
1342  Float_t v1= ev->GetValue(1);
1343  // if (ievt<3) std::cout<<ievt<<" var0="<<v0<<" var1="<<v1<<" weight="<<w<<std::endl;
1344  TH2* h;
1345  if (DataInfo().IsSignal(ev)) h=results->GetHist2D(Form("EventDistSig_%d",methodIndex));
1346  else h=results->GetHist2D(Form("EventDistBkg_%d",methodIndex));
1347  if (h) h->Fill(v0,v1,w);
1348  }
1349  }
1350  }
1351  }
1352 
1353  return;
1354 }
1355 
1356 
IMethod * Create(const std::string &name, const TString &job, const TString &title, DataSetInfo &dsi, const TString &option)
creates the method if needed based on the method name using the creator function the factory has stor...
static ClassifierFactory & Instance()
access to the ClassifierFactory singleton creates the instance if needed
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3159
Double_t GetBoostROCIntegral(Bool_t, Types::ETreeType, Bool_t CalcOverlapIntergral=kFALSE)
Calculate the ROC integral of a single classifier or even the whole boosted classifier.
float xmin
Definition: THbookFile.cxx:93
Random number generator class based on M.
Definition: TRandom3.h:29
void MonitorBoost(Types::EBoostStage stage, UInt_t methodIdx=0)
fill various monitoring histograms from information of the individual classifiers that have been boos...
std::vector< Float_t > * fMVAvalues
Definition: MethodBoost.h:192
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition: TRandom.cxx:414
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:162
TH1 * GetHist(const TString &alias) const
Definition: Results.cxx:113
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
long long Long64_t
Definition: RtypesCore.h:69
const Double_t * v1
Definition: TArcBall.cxx:33
void SingleTrain()
initialization
Stat_t GetSum() const
Definition: TArrayD.h:48
Double_t Bagging()
Bagging or Bootstrap boosting, gives new random poisson weight for every event.
Double_t Log(Double_t x)
Definition: TMath.h:526
virtual Double_t GetMvaValue(Double_t *errLower=0, Double_t *errUpper=0)=0
float Float_t
Definition: RtypesCore.h:53
Double_t AdaBoost(MethodBase *method, Bool_t useYesNoLeaf)
the standard (discrete or real) AdaBoost algorithm
virtual void WriteEvaluationHistosToFile(Types::ETreeType treetype)
writes all MVA evaluation histograms to file
Config & gConfig()
TH1 * h
Definition: legend2.C:5
virtual Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t)
Boost can handle classification with 2 classes and regression with one regression-target.
EAnalysisType
Definition: Types.h:124
void SetSignalReferenceCutOrientation(Double_t cutOrientation)
Definition: MethodBase.h:330
void SetBoostWeight(Double_t w) const
Definition: Event.h:110
Basic string class.
Definition: TString.h:137
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:570
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
int Int_t
Definition: RtypesCore.h:41
virtual TDirectory * mkdir(const char *name, const char *title="")
Create a sub-directory and return a pointer to the created directory.
Definition: TDirectory.cxx:955
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
const Ranking * CreateRanking()
Double_t GetWeight() const
return the event weight - depending on whether the flag IgnoreNegWeightsInTraining is or not...
Definition: Event.cxx:376
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
void ResetBoostWeights()
resetting back the boosted weights of the events to 1
virtual Bool_t IsSignalLike()
uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation) for...
Definition: MethodBase.cxx:845
TH2 * GetHist2D(const TString &alias) const
Definition: Results.cxx:122
static Types & Instance()
the the single instance of "Types" if existin already, or create it (Signleton)
Definition: Types.cxx:64
static void InhibitOutput()
Definition: MsgLogger.cxx:72
Tools & gTools()
Definition: Tools.cxx:79
void FindMVACut(MethodBase *method)
find the CUT on the individual MVA that defines an event as correct or misclassified (to be used in t...
TStopwatch timer
Definition: pirndm.C:37
MethodBoost(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption="", TDirectory *theTargetDir=NULL)
virtual Double_t GetBinLowEdge(Int_t bin) const
return bin lower edge for 1D historam Better to use h1.GetXaxis().GetBinLowEdge(bin) ...
Definition: TH1.cxx:8481
void AddEvent(Double_t val, Double_t weight, Int_t type)
void ProcessOptions()
process user options
Double_t SingleBoost(MethodBase *method)
virtual ~MethodBoost(void)
destructor
void ScaleBoostWeight(Double_t s) const
Definition: Event.h:111
virtual void SetMarkerColor(Color_t mcolor=1)
Definition: TAttMarker.h:51
Int_t GetNNodes()
Definition: MethodDT.h:111
std::vector< std::vector< double > > Data
Double_t NormHist(TH1 *theHist, Double_t norm=1.0)
normalises histogram
Definition: Tools.cxx:395
void GetHelpMessage() const
Get help message text.
Types::EMVA GetMethodType() const
Definition: MethodBase.h:298
Definition: PDF.h:71
Double_t GetOriginalWeight() const
Definition: Event.h:84
TString GetElapsedTime(Bool_t Scientific=kTRUE)
Definition: Timer.cxx:131
Bool_t BookMethod(Types::EMVA theMethod, TString methodTitle, TString theOption)
just registering the string from which the boosted classifier will be created
RooCmdArg Timer(Bool_t flag=kTRUE)
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:7014
std::string GetMethodName(TCppMethod_t)
Definition: Cppyy.cxx:706
TString dirName
Definition: demos.C:9
Service class for 2-Dim histogram classes.
Definition: TH2.h:36
SVector< double, 2 > v
Definition: Dict.h:5
TString GetMethodName(Types::EMVA method) const
Definition: Types.cxx:130
1-D histogram with a int per channel (see TH1 documentation)}
Definition: TH1.h:529
2-D histogram with a float per channel (see TH1 documentation)}
Definition: TH2.h:256
class TMVA::Config::VariablePlotting fVariablePlotting
virtual void WriteEvaluationHistosToFile(Types::ETreeType treetype)
writes all MVA evaluation histograms to file
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8543
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
char * Form(const char *fmt,...)
DataSetManager * fDataSetManager
tuple w
Definition: qtexample.py:51
TAxis * GetYaxis()
Definition: TH1.h:320
float xmax
Definition: THbookFile.cxx:93
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:613
REAL epsilon
Definition: triangle.c:617
void CreateMVAHistorgrams()
Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE)
Calculate a gaussian function with mean and sigma.
Definition: TMath.cxx:453
virtual Double_t GetSeparationGain(const Double_t &nSelS, const Double_t &nSelB, const Double_t &nTotS, const Double_t &nTotB)
Separation Gain: the measure of how the quality of separation of the sample increases by splitting th...
int Ssiz_t
Definition: RtypesCore.h:63
void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
Double_t Exp(Double_t x)
Definition: TMath.h:495
void CheckSetup()
check may be overridden by derived class (sometimes, eg, fitters are used which can only be implement...
double Double_t
Definition: RtypesCore.h:55
Describe directory structure in memory.
Definition: TDirectory.h:44
virtual Double_t GetROCIntegral(TH1D *histS, TH1D *histB) const
calculate the area (integral) under the ROC curve as a overall quality measure of the classification ...
int type
Definition: TGX11.cxx:120
void dir(char *path=0)
Definition: rootalias.C:30
TDirectory * BaseDir() const
returns the ROOT directory where info/histograms etc of the corresponding MVA method instance are sto...
Float_t GetValue(UInt_t ivar) const
return value of i'th variable
Definition: Event.cxx:231
The TH1 histogram class.
Definition: TH1.h:80
UInt_t GetClass() const
Definition: Event.h:86
Int_t GetNNodesBeforePruning()
Definition: MethodDT.h:110
virtual void TestClassification()
initialization
const TString & Color(const TString &)
human readable color strings
Definition: Tools.cxx:837
void WriteMonitoringHistosToFile(void) const
write special monitoring histograms to file dummy implementation here --------------— ...
#define REGISTER_METHOD(CLASS)
for example
std::vector< IMethod * > fMethods
Double_t GetMVAProbAt(Double_t value)
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Definition: TDirectory.cxx:433
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
Definition: MethodBase.cxx:606
virtual Double_t GetSeparationIndex(const Double_t &s, const Double_t &b)=0
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
void InitHistos()
initialisation routine
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
Definition: TDirectory.cxx:336
#define NULL
Definition: Rtypes.h:82
void DrawProgressBar(Int_t, const TString &comment="")
draws progress bar in color or B&W caution:
Definition: Timer.cxx:183
A TTree object has a header with a name and a title.
Definition: TTree.h:98
Double_t GetSignalReferenceCut() const
Definition: MethodBase.h:325
void Store(TObject *obj, const char *alias=0)
Definition: Results.cxx:69
static void EnableOutput()
Definition: MsgLogger.cxx:73
const Bool_t kTRUE
Definition: Rtypes.h:91
Int_t Fill(Double_t)
Invalid Fill method.
Definition: TH2.cxx:287
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
return boosted MVA response
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
void ComputeStat(const std::vector< TMVA::Event * > &, std::vector< Float_t > *, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Int_t signalClass, Bool_t norm=kFALSE)
sanity check
Definition: Tools.cxx:215
virtual void TestClassification()
initialization
Definition: math.cpp:60
TAxis * GetXaxis()
Definition: TH1.h:319
void SetSignalReferenceCut(Double_t cut)
Definition: MethodBase.h:329
ClassImp(TMVA::MethodBoost) TMVA
Definition: MethodBoost.cxx:82