120 const TString& theWeightFile) :
267 Log() <<
kFATAL <<
"Mechanism to ignore events with negative weights in training not yet available for method: " 269 <<
" --> please remove \"IgnoreNegWeightsInTraining\" option from booking string." 340 Log() <<
kINFO <<
"--------------------------------------" <<
Endl;
341 Log() <<
kINFO <<
"Friedmans RuleFit module is selected." <<
Endl;
342 Log() <<
kINFO <<
"Only the following options are used:" <<
Endl;
351 Log() <<
kINFO <<
"--------------------------------------" <<
Endl;
424 for (
Int_t ievt=0; ievt<nevents; ievt++){
468 <<
"please remove the optoin from the configuration string, or " 469 <<
"use \"!Normalise\"" 495 Log() <<
kDEBUG <<
"Computing rule and variable importance" <<
Endl;
506 for (
UInt_t i=0; i<nrules; i++ ) {
538 std::vector<const TMVA::Event*> tmp;
539 for (
Long64_t ievt=0; ievt<nevents; ievt++) {
541 tmp.push_back(event);
555 Log() <<
kDEBUG <<
"reading model summary from rf_go.exe output" <<
Endl;
560 Log() <<
kDEBUG <<
"calculating rule and variable importance" <<
Endl;
638 Int_t dp = fout.precision();
639 fout <<
" // not implemented for class: \"" << className <<
"\"" << std::endl;
640 fout <<
"};" << std::endl;
641 fout <<
"void " << className <<
"::Initialize(){}" << std::endl;
642 fout <<
"void " << className <<
"::Clear(){}" << std::endl;
643 fout <<
"double " << className <<
"::GetMvaValue__( const std::vector<double>& inputValues ) const {" << std::endl;
647 fout <<
" return rval;" << std::endl;
648 fout <<
"}" << std::endl;
649 fout << std::setprecision(dp);
657 Int_t dp = fout.precision();
659 fout <<
" //" << std::endl;
660 fout <<
" // ==> MODEL CONTAINS NO RULES <==" << std::endl;
661 fout <<
" //" << std::endl;
665 const std::vector< Rule* > *rules = &(rens->
GetRulesConst());
668 std::list< std::pair<Double_t,Int_t> > sortedRules;
669 for (
UInt_t ir=0; ir<rules->size(); ir++) {
670 sortedRules.push_back( std::pair<Double_t,Int_t>( (*rules)[ir]->GetImportance()/rens->
GetImportanceRef(),ir ) );
674 fout <<
" //" << std::endl;
675 fout <<
" // here follows all rules ordered in importance (most important first)" << std::endl;
676 fout <<
" // at the end of each line, the relative importance of the rule is given" << std::endl;
677 fout <<
" //" << std::endl;
679 for ( std::list< std::pair<double,int> >::reverse_iterator itpair = sortedRules.rbegin();
680 itpair != sortedRules.rend(); itpair++ ) {
681 UInt_t ir = itpair->second;
683 ruleCut = (*rules)[ir]->GetRuleCut();
684 if (impr<rens->GetImportanceCut()) fout <<
" //" << std::endl;
685 fout <<
" if (" << std::flush;
693 if (ic>0) fout <<
"&&" << std::flush;
695 fout <<
"(" << std::setprecision(10) << valmin << std::flush;
696 fout <<
"<inputValues[" << sel <<
"])" << std::flush;
699 if (domin) fout <<
"&&" << std::flush;
700 fout <<
"(inputValues[" << sel <<
"]" << std::flush;
701 fout <<
"<" << std::setprecision(10) << valmax <<
")" <<std::flush;
704 fout <<
") rval+=" << std::setprecision(10) << (*rules)[ir]->GetCoefficient() <<
";" << std::flush;
705 fout <<
" // importance = " <<
Form(
"%3.3f",impr) << std::endl;
707 fout << std::setprecision(dp);
716 fout <<
" //" << std::endl;
717 fout <<
" // ==> MODEL CONTAINS NO LINEAR TERMS <==" << std::endl;
718 fout <<
" //" << std::endl;
721 fout <<
" //" << std::endl;
722 fout <<
" // here follows all linear terms" << std::endl;
723 fout <<
" // at the end of each line, the relative importance of the term is given" << std::endl;
724 fout <<
" //" << std::endl;
727 for (
UInt_t il=0; il<nlin; il++) {
735 <<
"*std::min( double(" << std::setprecision(10) << rens->
GetLinDP(il)
736 <<
"), std::max( double(inputValues[" << il <<
"]), double(" << std::setprecision(10) << rens->
GetLinDM(il) <<
")));" 738 fout <<
" // importance = " <<
Form(
"%3.3f",imp) << std::endl;
756 Log() << col <<
"--- Short description:" << colres <<
Endl;
758 Log() <<
"This method uses a collection of so called rules to create a" <<
Endl;
759 Log() <<
"discriminating scoring function. Each rule consists of a series" <<
Endl;
760 Log() <<
"of cuts in parameter space. The ensemble of rules are created" <<
Endl;
761 Log() <<
"from a forest of decision trees, trained using the training data." <<
Endl;
762 Log() <<
"Each node (apart from the root) corresponds to one rule." <<
Endl;
763 Log() <<
"The scoring function is then obtained by linearly combining" <<
Endl;
764 Log() <<
"the rules. A fitting procedure is applied to find the optimum" <<
Endl;
765 Log() <<
"set of coefficients. The goal is to find a model with few rules" <<
Endl;
766 Log() <<
"but with a strong discriminating power." <<
Endl;
768 Log() << col <<
"--- Performance optimisation:" << colres <<
Endl;
770 Log() <<
"There are two important considerations to make when optimising:" <<
Endl;
772 Log() <<
" 1. Topology of the decision tree forest" << brk <<
Endl;
773 Log() <<
" 2. Fitting of the coefficients" <<
Endl;
775 Log() <<
"The maximum complexity of the rules is defined by the size of" <<
Endl;
776 Log() <<
"the trees. Large trees will yield many complex rules and capture" <<
Endl;
777 Log() <<
"higher order correlations. On the other hand, small trees will" <<
Endl;
778 Log() <<
"lead to a smaller ensemble with simple rules, only capable of" <<
Endl;
779 Log() <<
"modeling simple structures." <<
Endl;
780 Log() <<
"Several parameters exists for controlling the complexity of the" <<
Endl;
781 Log() <<
"rule ensemble." <<
Endl;
783 Log() <<
"The fitting procedure searches for a minimum using a gradient" <<
Endl;
784 Log() <<
"directed path. Apart from step size and number of steps, the" <<
Endl;
785 Log() <<
"evolution of the path is defined by a cut-off parameter, tau." <<
Endl;
786 Log() <<
"This parameter is unknown and depends on the training data." <<
Endl;
787 Log() <<
"A large value will tend to give large weights to a few rules." <<
Endl;
788 Log() <<
"Similarily, a small value will lead to a large set of rules" <<
Endl;
789 Log() <<
"with similar weights." <<
Endl;
791 Log() <<
"A final point is the model used; rules and/or linear terms." <<
Endl;
792 Log() <<
"For a given training sample, the result may improve by adding" <<
Endl;
793 Log() <<
"linear terms. If best performance is optained using only linear" <<
Endl;
794 Log() <<
"terms, it is very likely that the Fisher discriminant would be" <<
Endl;
795 Log() <<
"a better choice. Ideally the fitting procedure should be able to" <<
Endl;
796 Log() <<
"make this choice by giving appropriate weights for either terms." <<
Endl;
798 Log() << col <<
"--- Performance tuning via configuration options:" << colres <<
Endl;
800 Log() <<
"I. TUNING OF RULE ENSEMBLE:" <<
Endl;
802 Log() <<
" " << col <<
"ForestType " << colres
803 <<
": Recomended is to use the default \"AdaBoost\"." << brk <<
Endl;
804 Log() <<
" " << col <<
"nTrees " << colres
805 <<
": More trees leads to more rules but also slow" <<
Endl;
806 Log() <<
" performance. With too few trees the risk is" <<
Endl;
807 Log() <<
" that the rule ensemble becomes too simple." << brk <<
Endl;
808 Log() <<
" " << col <<
"fEventsMin " << colres << brk <<
Endl;
809 Log() <<
" " << col <<
"fEventsMax " << colres
810 <<
": With a lower min, more large trees will be generated" <<
Endl;
811 Log() <<
" leading to more complex rules." <<
Endl;
812 Log() <<
" With a higher max, more small trees will be" <<
Endl;
813 Log() <<
" generated leading to more simple rules." <<
Endl;
814 Log() <<
" By changing this range, the average complexity" <<
Endl;
815 Log() <<
" of the rule ensemble can be controlled." << brk <<
Endl;
816 Log() <<
" " << col <<
"RuleMinDist " << colres
817 <<
": By increasing the minimum distance between" <<
Endl;
818 Log() <<
" rules, fewer and more diverse rules will remain." <<
Endl;
819 Log() <<
" Initially it is a good idea to keep this small" <<
Endl;
820 Log() <<
" or zero and let the fitting do the selection of" <<
Endl;
821 Log() <<
" rules. In order to reduce the ensemble size," <<
Endl;
822 Log() <<
" the value can then be increased." <<
Endl;
825 Log() <<
"II. TUNING OF THE FITTING:" <<
Endl;
827 Log() <<
" " << col <<
"GDPathEveFrac " << colres
828 <<
": fraction of events in path evaluation" <<
Endl;
829 Log() <<
" Increasing this fraction will improve the path" <<
Endl;
830 Log() <<
" finding. However, a too high value will give few" <<
Endl;
831 Log() <<
" unique events available for error estimation." <<
Endl;
832 Log() <<
" It is recomended to usethe default = 0.5." << brk <<
Endl;
833 Log() <<
" " << col <<
"GDTau " << colres
834 <<
": cutoff parameter tau" <<
Endl;
835 Log() <<
" By default this value is set to -1.0." <<
Endl;
837 Log() <<
" This means that the cut off parameter is" <<
Endl;
838 Log() <<
" automatically estimated. In most cases" <<
Endl;
839 Log() <<
" this should be fine. However, you may want" <<
Endl;
840 Log() <<
" to fix this value if you already know it" <<
Endl;
841 Log() <<
" and want to reduce on training time." << brk <<
Endl;
842 Log() <<
" " << col <<
"GDTauPrec " << colres
843 <<
": precision of estimated tau" <<
Endl;
844 Log() <<
" Increase this precision to find a more" <<
Endl;
845 Log() <<
" optimum cut-off parameter." << brk <<
Endl;
846 Log() <<
" " << col <<
"GDNStep " << colres
847 <<
": number of steps in path search" <<
Endl;
848 Log() <<
" If the number of steps is too small, then" <<
Endl;
849 Log() <<
" the program will give a warning message." <<
Endl;
851 Log() <<
"III. WARNING MESSAGES" <<
Endl;
853 Log() << col <<
"Risk(i+1)>=Risk(i) in path" << colres << brk <<
Endl;
854 Log() << col <<
"Chaotic behaviour of risk evolution." << colres <<
Endl;
856 Log() <<
" The error rate was still decreasing at the end" <<
Endl;
857 Log() <<
" By construction the Risk should always decrease." <<
Endl;
858 Log() <<
" However, if the training sample is too small or" <<
Endl;
859 Log() <<
" the model is overtrained, such warnings can" <<
Endl;
861 Log() <<
" The warnings can safely be ignored if only a" <<
Endl;
862 Log() <<
" few (<3) occur. If more warnings are generated," <<
Endl;
863 Log() <<
" the fitting fails." <<
Endl;
864 Log() <<
" A remedy may be to increase the value" << brk <<
Endl;
866 << col <<
"GDValidEveFrac" << colres
867 <<
" to 1.0 (or a larger value)." << brk <<
Endl;
868 Log() <<
" In addition, if " 869 << col <<
"GDPathEveFrac" << colres
870 <<
" is too high" <<
Endl;
871 Log() <<
" the same warnings may occur since the events" <<
Endl;
872 Log() <<
" used for error estimation are also used for" <<
Endl;
873 Log() <<
" path estimation." <<
Endl;
874 Log() <<
" Another possibility is to modify the model - " <<
Endl;
875 Log() <<
" See above on tuning the rule ensemble." <<
Endl;
877 Log() << col <<
"The error rate was still decreasing at the end of the path" 879 Log() <<
" Too few steps in path! Increase " 880 << col <<
"GDNSteps" << colres <<
"." <<
Endl;
882 Log() << col <<
"Reached minimum early in the search" << colres <<
Endl;
884 Log() <<
" Minimum was found early in the fitting. This" <<
Endl;
885 Log() <<
" may indicate that the used step size " 886 << col <<
"GDStep" << colres <<
"." <<
Endl;
887 Log() <<
" was too large. Reduce it and rerun." <<
Endl;
888 Log() <<
" If the results still are not OK, modify the" <<
Endl;
889 Log() <<
" model either by modifying the rule ensemble" <<
Endl;
890 Log() <<
" or add/remove linear terms" <<
Endl;
void DeclareOptions()
define the options (their key words) that can be set in the option string know options.
void Init(void)
default initialization
Double_t GetImportanceRef() const
void WelcomeMessage()
welcome message
void ReadWeightsFromXML(void *wghtnode)
read rules from XML node
MsgLogger & Endl(MsgLogger &ml)
Double_t GetRulePBS(int i) const
const RuleEnsemble & GetRuleEnsemble() const
void WriteMonitoringHistosToFile(void) const
write special monitoring histograms to file (here ntuple)
void ReadWeightsFromStream(std::istream &istr)
read rules from an std::istream
void CalcImportance()
calculates the importance of each rule
Double_t GetRulePTag(int i) const
const std::vector< Double_t > & GetLinNorm() const
UInt_t GetNLinear() const
virtual Int_t Fill()
Fill all branches.
void SetGDTau(Double_t t)
void SetMsgType(EMsgType t)
set the current message type to that of mlog for this class and all other subtools ...
OptionBase * DeclareOptionRef(T &ref, const TString &name, const TString &desc="")
void InitMonitorNtuple()
initialize the monitoring ntuple
const std::vector< TMVA::Rule * > & GetRulesConst() const
void FitCoefficients()
Fit the coefficients for the rule ensemble.
const RuleCut * GetRuleCut() const
const std::vector< Double_t > & GetVarImportance() const
void SetGDTauPrec(Double_t p)
void ToLower()
Change string to lower-case.
const Ranking * CreateRanking()
computes ranking of input variables
void TrainJFRuleFit()
training of rules using Jerome Friedmans implementation
Double_t GetCutMin(Int_t is) const
void SetTrainingEvents(const std::vector< const TMVA::Event *> &el)
set the training events randomly
const std::vector< Double_t > & GetLinCoefficients() const
MethodRuleFit(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption="")
standard constructor
const TString & GetInputLabel(Int_t i) const
Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
returns MVA value for given event
TMVA::DecisionTree::EPruneMethod fPruneMethod
void ProcessOptions()
process the options specified by the user
Char_t GetCutDoMin(Int_t is) const
const std::vector< Double_t > & GetLinImportance() const
void UseImportanceVisHists()
const Event * GetEvent() const
void MakeClassSpecific(std::ostream &, const TString &) const
write specific classifier response
void Print() const
print function
void SetGDErrScale(Double_t s)
void MakeClassLinear(std::ostream &) const
print out the linear terms
std::vector< TMVA::Event * > fEventSample
Bool_t ReadModelSum()
read model from rulefit.sum
void TrainTMVARuleFit()
training of rules using TMVA implementation
RuleEnsemble * GetRuleEnsemblePtr()
Long64_t GetNTrainingEvents() const
Char_t GetCutDoMax(Int_t is) const
void SetGDNPathSteps(Int_t np)
UInt_t GetNEvents() const
temporary event when testing on a different DataSet than the own one
Double_t GetRulePSB(int i) const
void SetGDTauScan(UInt_t n)
SeparationBase * fSepType
Double_t GetRulePBB(int i) const
void * AddXMLTo(void *parent) const
write rules to XML
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Bool_t HasTrainingTree() const
RuleFitParams * GetRuleFitParamsPtr()
UInt_t GetNcuts() const
get number of cuts
const char * GetName() const
Double_t GetCoefficient() const
void MakeDebugHists()
this will create a histograms intended rather for debugging or for the curious user ...
char * Form(const char *fmt,...)
virtual const char * GetPath() const
Returns the full path of the directory.
Bool_t IsLinTermOK(int i) const
Double_t GetRulePSS(int i) const
void ReadFromXML(void *wghtnode)
read rules from XML
void GetHelpMessage() const
get help message text
Bool_t VerifyRange(MsgLogger &mlog, const char *varstr, T &var, const T &vmin, const T &vmax)
Bool_t IgnoreEventsWithNegWeightsInTraining() const
Double_t GetRelImportance() const
Bool_t WriteOptionsReference() const
Bool_t IsNormalised() const
void MakeVisHists()
this will create histograms visualizing the rule ensemble
Double_t GetLinDM(int i) const
void SetCurrentType(Types::ETreeType type) const
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
void AddPreDefVal(const T &)
void InitPtrs(const TMVA::MethodBase *rfbase)
initialize pointers
void SetGDTauRange(Double_t t0, Double_t t1)
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
UInt_t GetSelector(Int_t is) const
void SetRuleMinDist(Double_t d)
Double_t GetOffset() const
#define REGISTER_METHOD(CLASS)
for example
Abstract ClassifierFactory template that handles arbitrary types.
Bool_t IsSignalRule() const
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
TDirectory * BaseDir() const
returns the ROOT directory where info/histograms etc of the corresponding MVA method instance are sto...
TString GetMethodTypeName() const
virtual void AddRank(const Rank &rank)
Add a new rank take ownership of it.
Double_t GetCutMax(Int_t is) const
Long64_t GetNEvents(Types::ETreeType type=Types::kMaxTreeType) const
Double_t GetLinDP(int i) const
Double_t EvalEvent(const Event &e)
evaluate single event
A TTree object has a header with a name and a title.
virtual Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t)
RuleFit can handle classification with 2 classes.
virtual ~MethodRuleFit(void)
destructor
void Initialize(const TMVA::MethodBase *rfbase)
initialize the parameters of the RuleFit method and make rules
void MakeClassRuleCuts(std::ostream &) const
print out the rule cuts
double norm(double *x, double *p)
Double_t GetSupport() const
std::vector< DecisionTree * > fForest
void SetGDPathStep(Double_t s)
void SetImportanceCut(Double_t minimp=0)
void AddWeightsXMLTo(void *parent) const
add the rules to XML node
void NoErrorCalc(Double_t *const err, Double_t *const errUpper)
void SetSignalReferenceCut(Double_t cut)
void InitEventSample(void)
write all Events from the Tree into a vector of Events, that are more easily manipulated.
void SetLinQuantile(Double_t q)
void ReadRaw(std::istream &istr)
read rule ensemble from stream