141   fTheMethod    ( 
"Fisher" ),
 
  142   fFisherMethod ( kFisher ),
 
  158                                  const TString& theWeightFile) :
 
  161   fTheMethod    ( 
"Fisher" ),
 
  162   fFisherMethod ( kFisher ),
 
  180   fFisherCoeff = 
new std::vector<Double_t>( GetNvar() );
 
  183   SetSignalReferenceCut( 0.0 );
 
  196   DeclareOptionRef( fTheMethod = 
"Fisher", 
"Method", 
"Discrimination method" );
 
  197   AddPreDefVal(
TString(
"Fisher"));
 
  198   AddPreDefVal(
TString(
"Mahalanobis"));
 
  206   if (fTheMethod ==  
"Fisher" ) fFisherMethod = kFisher;
 
  207   else                          fFisherMethod = kMahalanobis;
 
  218   if (fBetw       ) { 
delete fBetw; fBetw = 0; }
 
  219   if (fWith       ) { 
delete fWith; fWith = 0; }
 
  220   if (fCov        ) { 
delete fCov;  fCov = 0; }
 
  221   if (fDiscrimPow ) { 
delete fDiscrimPow; fDiscrimPow = 0; }
 
  222   if (fFisherCoeff) { 
delete fFisherCoeff; fFisherCoeff = 0; }
 
  243   GetCov_WithinClass();
 
  246   GetCov_BetweenClass();
 
  270   const Event * ev = GetEvent();
 
  272   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++)
 
  273      result += (*fFisherCoeff)[ivar]*ev->
GetValue(ivar);
 
  276   NoErrorCalc(err, errUpper);
 
  288   fMeanMatx = 
new TMatrixD( GetNvar(), 3 );
 
  291   fBetw = 
new TMatrixD( GetNvar(), GetNvar() );
 
  292   fWith = 
new TMatrixD( GetNvar(), GetNvar() );
 
  293   fCov  = 
new TMatrixD( GetNvar(), GetNvar() );
 
  296   fDiscrimPow = 
new std::vector<Double_t>( GetNvar() );
 
  308   const UInt_t nvar = DataInfo().GetNVariables();
 
  313   for (
UInt_t ivar=0; ivar<nvar; ivar++) { sumS[ivar] = sumB[ivar] = 0; }
 
  316   for (
Int_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
 
  319      const Event * ev = GetEvent(ievt);
 
  323      if (DataInfo().IsSignal(ev)) fSumOfWeightsS += weight;
 
  324      else                         fSumOfWeightsB += weight;
 
  326      Double_t* 
sum = DataInfo().IsSignal(ev) ? sumS : sumB;
 
  331   for (
UInt_t ivar=0; ivar<nvar; ivar++) {
 
  332      (*fMeanMatx)( ivar, 2 ) = sumS[ivar];
 
  333      (*fMeanMatx)( ivar, 0 ) = sumS[ivar]/fSumOfWeightsS;
 
  335      (*fMeanMatx)( ivar, 2 ) += sumB[ivar];
 
  336      (*fMeanMatx)( ivar, 1 ) = sumB[ivar]/fSumOfWeightsB;
 
  339      (*fMeanMatx)( ivar, 2 ) /= (fSumOfWeightsS + fSumOfWeightsB);
 
  354   assert( fSumOfWeightsS > 0 && fSumOfWeightsB > 0 );
 
  359   const Int_t nvar  = GetNvar();
 
  360   const Int_t nvar2 = nvar*nvar;
 
  364   memset(sumSig,0,nvar2*
sizeof(
Double_t));
 
  365   memset(sumBgd,0,nvar2*
sizeof(
Double_t));
 
  368   for (
Int_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
 
  371      const Event* ev = GetEvent(ievt);
 
  379            if (DataInfo().IsSignal(ev)) {
 
  380               Double_t v = ( (xval[
x] - (*fMeanMatx)(
x, 0))*(xval[
y] - (*fMeanMatx)(
y, 0)) )*weight;
 
  383               Double_t v = ( (xval[
x] - (*fMeanMatx)(
x, 1))*(xval[
y] - (*fMeanMatx)(
y, 1)) )*weight;
 
  402         (*fWith)(
x, 
y) = sumSig[k]/fSumOfWeightsS + sumBgd[k]/fSumOfWeightsB;
 
  420   assert( fSumOfWeightsS > 0 && fSumOfWeightsB > 0);
 
  427         prodSig = ( ((*fMeanMatx)(
x, 0) - (*fMeanMatx)(
x, 2))*
 
  428                     ((*fMeanMatx)(
y, 0) - (*fMeanMatx)(
y, 2)) );
 
  429         prodBgd = ( ((*fMeanMatx)(
x, 1) - (*fMeanMatx)(
x, 2))*
 
  430                     ((*fMeanMatx)(
y, 1) - (*fMeanMatx)(
y, 2)) );
 
  432         (*fBetw)(
x, 
y) = (fSumOfWeightsS*prodSig + fSumOfWeightsB*prodBgd) / (fSumOfWeightsS + fSumOfWeightsB);
 
  444         (*fCov)(
x, 
y) = (*fWith)(
x, 
y) + (*fBetw)(
x, 
y);
 
  460   assert( fSumOfWeightsS > 0 && fSumOfWeightsB > 0);
 
  464   switch (GetFisherMethod()) {
 
  472      Log() << kFATAL << 
"<GetFisherCoeff> undefined method" << GetFisherMethod() << 
Endl;
 
  478      Log() << kWARNING << 
"<GetFisherCoeff> matrix is almost singular with determinant=" 
  480            << 
" did you use the variables that are linear combinations or highly correlated?" 
  485      Log() << kFATAL << 
"<GetFisherCoeff> matrix is singular with determinant=" 
  487            << 
" did you use the variables that are linear combinations? \n" 
  488            << 
" do you any clue as to what went wrong in above printout of the covariance matrix? " 
  495   Double_t xfact = 
TMath::Sqrt( fSumOfWeightsS*fSumOfWeightsB ) / (fSumOfWeightsS + fSumOfWeightsB);
 
  498   std::vector<Double_t> diffMeans( GetNvar() );
 
  500   for (ivar=0; ivar<GetNvar(); ivar++) {
 
  501      (*fFisherCoeff)[ivar] = 0;
 
  503      for (jvar=0; jvar<GetNvar(); jvar++) {
 
  504         Double_t d = (*fMeanMatx)(jvar, 0) - (*fMeanMatx)(jvar, 1);
 
  505         (*fFisherCoeff)[ivar] += invCov(ivar, jvar)*
d;
 
  508      (*fFisherCoeff)[ivar] *= xfact;
 
  514   for (ivar=0; ivar<GetNvar(); ivar++){
 
  515      fF0 += (*fFisherCoeff)[ivar]*((*fMeanMatx)(ivar, 0) + (*fMeanMatx)(ivar, 1));
 
  530   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  531      if ((*fCov)(ivar, ivar) != 0)
 
  532         (*fDiscrimPow)[ivar] = (*fBetw)(ivar, ivar)/(*fCov)(ivar, ivar);
 
  534         (*fDiscrimPow)[ivar] = 0;
 
  546   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  547      fRanking->AddRank( 
Rank( GetInputLabel(ivar), (*fDiscrimPow)[ivar] ) );
 
  559   Log() << kHEADER << 
"Results for Fisher coefficients:" << 
Endl;
 
  561   if (GetTransformationHandler().GetTransformationList().GetSize() != 0) {
 
  562      Log() << kINFO << 
"NOTE: The coefficients must be applied to TRANFORMED variables" << 
Endl;
 
  563      Log() << kINFO << 
"  List of the transformation: " << 
Endl;
 
  564      TListIter trIt(&GetTransformationHandler().GetTransformationList());
 
  566         Log() << kINFO << 
"  -- " << trf->GetName() << 
Endl;
 
  569   std::vector<TString>  vars;
 
  570   std::vector<Double_t> coeffs;
 
  571   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  572      vars  .push_back( GetInputLabel(ivar) );
 
  573      coeffs.push_back(  (*fFisherCoeff)[ivar] );
 
  575   vars  .push_back( 
"(offset)" );
 
  576   coeffs.push_back( fF0 );
 
  582   if (IsNormalised()) {
 
  583      Log() << kINFO << 
"NOTE: You have chosen to use the \"Normalise\" booking option. Hence, the" << 
Endl;
 
  584      Log() << kINFO << 
"      coefficients must be applied to NORMALISED (') variables as follows:" << 
Endl;
 
  586      for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) 
if (GetInputLabel(ivar).Length() > maxL) maxL = GetInputLabel(ivar).Length();
 
  589      for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  591               << std::setw(maxL+9) << 
TString(
"[") + GetInputLabel(ivar) + 
"]' = 2*(" 
  592               << std::setw(maxL+2) << 
TString(
"[") + GetInputLabel(ivar) + 
"]" 
  593               << std::setw(3) << (GetXmin(ivar) > 0 ? 
" - " : 
" + ")
 
  594               << std::setw(6) << 
TMath::Abs(GetXmin(ivar)) << std::setw(3) << 
")/" 
  595               << std::setw(6) << (GetXmax(ivar) -  GetXmin(ivar) )
 
  596               << std::setw(3) << 
" - 1" 
  599      Log() << kINFO << 
"The TMVA Reader will properly account for this normalisation, but if the" << 
Endl;
 
  600      Log() << kINFO << 
"Fisher classifier is applied outside the Reader, the transformation must be" << 
Endl;
 
  601      Log() << kINFO << 
"implemented -- or the \"Normalise\" option is removed and Fisher retrained." << 
Endl;
 
  612   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) istr >> (*fFisherCoeff)[ivar];
 
  625   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  628      gTools().
AddAttr( coeffxml, 
"Value", (*fFisherCoeff)[ivar] );
 
  639   fFisherCoeff->resize(ncoeff-1);
 
  646      if (coeffidx==0) fF0 = coeff;
 
  647      else             (*fFisherCoeff)[coeffidx-1] = coeff;
 
  657   Int_t dp = fout.precision();
 
  658   fout << 
"   double              fFisher0;" << std::endl;
 
  659   fout << 
"   std::vector<double> fFisherCoefficients;" << std::endl;
 
  660   fout << 
"};" << std::endl;
 
  661   fout << 
"" << std::endl;
 
  662   fout << 
"inline void " << className << 
"::Initialize() " << std::endl;
 
  663   fout << 
"{" << std::endl;
 
  664   fout << 
"   fFisher0 = " << std::setprecision(12) << fF0 << 
";" << std::endl;
 
  665   for (
UInt_t ivar=0; ivar<GetNvar(); ivar++) {
 
  666      fout << 
"   fFisherCoefficients.push_back( " << std::setprecision(12) << (*fFisherCoeff)[ivar] << 
" );" << std::endl;
 
  669   fout << 
"   // sanity check" << std::endl;
 
  670   fout << 
"   if (fFisherCoefficients.size() != fNvars) {" << std::endl;
 
  671   fout << 
"      std::cout << \"Problem in class \\\"\" << fClassName << \"\\\"::Initialize: mismatch in number of input values\"" << std::endl;
 
  672   fout << 
"                << fFisherCoefficients.size() << \" != \" << fNvars << std::endl;" << std::endl;
 
  673   fout << 
"      fStatusIsClean = false;" << std::endl;
 
  674   fout << 
"   }         " << std::endl;
 
  675   fout << 
"}" << std::endl;
 
  677   fout << 
"inline double " << className << 
"::GetMvaValue__( const std::vector<double>& inputValues ) const" << std::endl;
 
  678   fout << 
"{" << std::endl;
 
  679   fout << 
"   double retval = fFisher0;" << std::endl;
 
  680   fout << 
"   for (size_t ivar = 0; ivar < fNvars; ivar++) {" << std::endl;
 
  681   fout << 
"      retval += fFisherCoefficients[ivar]*inputValues[ivar];" << std::endl;
 
  682   fout << 
"   }" << std::endl;
 
  684   fout << 
"   return retval;" << std::endl;
 
  685   fout << 
"}" << std::endl;
 
  687   fout << 
"// Clean up" << std::endl;
 
  688   fout << 
"inline void " << className << 
"::Clear() " << std::endl;
 
  689   fout << 
"{" << std::endl;
 
  690   fout << 
"   // clear coefficients" << std::endl;
 
  691   fout << 
"   fFisherCoefficients.clear(); " << std::endl;
 
  692   fout << 
"}" << std::endl;
 
  693   fout << std::setprecision(dp);
 
  707   Log() << 
"Fisher discriminants select events by distinguishing the mean " << 
Endl;
 
  708   Log() << 
"values of the signal and background distributions in a trans- " << 
Endl;
 
  709   Log() << 
"formed variable space where linear correlations are removed." << 
Endl;
 
  711   Log() << 
"   (More precisely: the \"linear discriminator\" determines" << 
Endl;
 
  712   Log() << 
"    an axis in the (correlated) hyperspace of the input " << 
Endl;
 
  713   Log() << 
"    variables such that, when projecting the output classes " << 
Endl;
 
  714   Log() << 
"    (signal and background) upon this axis, they are pushed " << 
Endl;
 
  715   Log() << 
"    as far as possible away from each other, while events" << 
Endl;
 
  716   Log() << 
"    of a same class are confined in a close vicinity. The  " << 
Endl;
 
  717   Log() << 
"    linearity property of this classifier is reflected in the " << 
Endl;
 
  718   Log() << 
"    metric with which \"far apart\" and \"close vicinity\" are " << 
Endl;
 
  719   Log() << 
"    determined: the covariance matrix of the discriminating" << 
Endl;
 
  720   Log() << 
"    variable space.)" << 
Endl;
 
  724   Log() << 
"Optimal performance for Fisher discriminants is obtained for " << 
Endl;
 
  725   Log() << 
"linearly correlated Gaussian-distributed variables. Any deviation" << 
Endl;
 
  726   Log() << 
"from this ideal reduces the achievable separation power. In " << 
Endl;
 
  727   Log() << 
"particular, no discrimination at all is achieved for a variable" << 
Endl;
 
  728   Log() << 
"that has the same sample mean for signal and background, even if " << 
Endl;
 
  729   Log() << 
"the shapes of the distributions are very different. Thus, Fisher " << 
Endl;
 
  730   Log() << 
"discriminants often benefit from suitable transformations of the " << 
Endl;
 
  731   Log() << 
"input variables. For example, if a variable x in [-1,1] has a " << 
Endl;
 
  732   Log() << 
"a parabolic signal distributions, and a uniform background" << 
Endl;
 
  733   Log() << 
"distributions, their mean value is zero in both cases, leading " << 
Endl;
 
  734   Log() << 
"to no separation. The simple transformation x -> |x| renders this " << 
Endl;
 
  735   Log() << 
"variable powerful for the use in a Fisher discriminant." << 
Endl;
 
#define REGISTER_METHOD(CLASS)
for example
TMatrixT< Double_t > TMatrixD
Class that contains all the data information.
Float_t GetValue(UInt_t ivar) const
return value of i'th variable
Double_t GetWeight() const
return the event weight - depending on whether the flag IgnoreNegWeightsInTraining is or not.
Virtual base Class for all MVA method.
Fisher and Mahalanobis Discriminants (Linear Discriminant Analysis)
void ReadWeightsFromStream(std::istream &i)
read Fisher coefficients from weight file
void GetCov_Full(void)
compute full covariance matrix from sum of within and between matrices
void GetHelpMessage() const
get help message text
MethodFisher(const TString &jobName, const TString &methodTitle, DataSetInfo &dsi, const TString &theOption="Fisher")
standard constructor for the "Fisher"
const Ranking * CreateRanking()
computes ranking of input variables
virtual ~MethodFisher(void)
destructor
void Train(void)
computation of Fisher coefficients by series of matrix operations
void GetDiscrimPower(void)
computation of discrimination power indicator for each variable small values of "fWith" indicates lit...
virtual Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets)
Fisher can only handle classification with 2 classes.
void PrintCoefficients(void)
display Fisher coefficients and discriminating power for each variable check maximum length of variab...
void GetCov_BetweenClass(void)
the matrix of covariance 'between class' reflects the dispersion of the events of a class relative to...
void MakeClassSpecific(std::ostream &, const TString &) const
write Fisher-specific classifier response
void ReadWeightsFromXML(void *wghtnode)
read Fisher coefficients from xml weight file
void ProcessOptions()
process user options
void GetFisherCoeff(void)
Fisher = Sum { [coeff]*[variables] }.
void GetMean(void)
compute mean values of variables in each sample, and the overall means
void AddWeightsXMLTo(void *parent) const
create XML description of Fisher classifier
void DeclareOptions()
MethodFisher options: format and syntax of option string: "type" where type is "Fisher" or "Mahalanob...
Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
returns the Fisher value (no fixed range)
void InitMatrices(void)
initialization method; creates global matrices and vectors
void GetCov_WithinClass(void)
the matrix of covariance 'within class' reflects the dispersion of the events relative to the center ...
void Init(void)
default initialization called by all constructors
Ranking for variables in method (implementation)
Singleton class for Global types used by TMVA.
void Print(Option_t *name="") const
Print the matrix as a table of elements.
TMatrixT< Element > & Invert(Double_t *det=0)
Invert the matrix and calculate its determinant.
virtual Double_t Determinant() const
Return the matrix determinant.
std::string GetName(const std::string &scope_name)
MsgLogger & Endl(MsgLogger &ml)
constexpr Double_t E()
Base of natural log:
Double_t Sqrt(Double_t x)
static long int sum(long int i)