157 const TString& theWeightFile) :
312 for (
UInt_t ivar=0; ivar<nvar; ivar++) { sumS[ivar] = sumB[ivar] = 0; }
315 for (
Int_t ievt=0; ievt<
Data()->GetNEvents(); ievt++) {
330 for (
UInt_t ivar=0; ivar<nvar; ivar++) {
331 (*fMeanMatx)( ivar, 2 ) = sumS[ivar];
334 (*fMeanMatx)( ivar, 2 ) += sumB[ivar];
359 const Int_t nvar2 = nvar*nvar;
363 memset(sumSig,0,nvar2*
sizeof(
Double_t));
364 memset(sumBgd,0,nvar2*
sizeof(
Double_t));
367 for (
Int_t ievt=0; ievt<
Data()->GetNEvents(); ievt++) {
379 Double_t v = ( (xval[
x] - (*fMeanMatx)(
x, 0))*(xval[
y] - (*fMeanMatx)(
y, 0)) )*weight;
382 Double_t v = ( (xval[
x] - (*fMeanMatx)(
x, 1))*(xval[
y] - (*fMeanMatx)(
y, 1)) )*weight;
426 prodSig = ( ((*fMeanMatx)(
x, 0) - (*fMeanMatx)(
x, 2))*
427 ((*fMeanMatx)(
y, 0) - (*fMeanMatx)(
y, 2)) );
428 prodBgd = ( ((*fMeanMatx)(
x, 1) - (*fMeanMatx)(
x, 2))*
429 ((*fMeanMatx)(
y, 1) - (*fMeanMatx)(
y, 2)) );
477 Log() << kWARNING <<
"<GetFisherCoeff> matrix is almost singular with determinant="
479 <<
" did you use the variables that are linear combinations or highly correlated?"
484 Log() << kFATAL <<
"<GetFisherCoeff> matrix is singular with determinant="
486 <<
" did you use the variables that are linear combinations? \n"
487 <<
" do you any clue as to what went wrong in above printout of the covariance matrix? "
497 std::vector<Double_t> diffMeans(
GetNvar() );
499 for (ivar=0; ivar<
GetNvar(); ivar++) {
500 (*fFisherCoeff)[ivar] = 0;
502 for (jvar=0; jvar<
GetNvar(); jvar++) {
504 (*fFisherCoeff)[ivar] += invCov(ivar, jvar)*
d;
507 (*fFisherCoeff)[ivar] *= xfact;
513 for (ivar=0; ivar<
GetNvar(); ivar++){
514 fF0 += (*fFisherCoeff)[ivar]*((*fMeanMatx)(ivar, 0) + (*fMeanMatx)(ivar, 1));
530 if ((*
fCov)(ivar, ivar) != 0)
531 (*fDiscrimPow)[ivar] = (*fBetw)(ivar, ivar)/(*
fCov)(ivar, ivar);
558 Log() << kHEADER <<
"Results for Fisher coefficients:" <<
Endl;
561 Log() << kINFO <<
"NOTE: The coefficients must be applied to TRANFORMED variables" <<
Endl;
562 Log() << kINFO <<
" List of the transformation: " <<
Endl;
565 Log() << kINFO <<
" -- " << trf->GetName() <<
Endl;
568 std::vector<TString> vars;
569 std::vector<Double_t> coeffs;
574 vars .push_back(
"(offset)" );
575 coeffs.push_back(
fF0 );
582 Log() << kINFO <<
"NOTE: You have chosen to use the \"Normalise\" booking option. Hence, the" <<
Endl;
583 Log() << kINFO <<
" coefficients must be applied to NORMALISED (') variables as follows:" <<
Endl;
592 << std::setw(3) << (
GetXmin(ivar) > 0 ?
" - " :
" + ")
595 << std::setw(3) <<
" - 1"
598 Log() << kINFO <<
"The TMVA Reader will properly account for this normalisation, but if the" <<
Endl;
599 Log() << kINFO <<
"Fisher classifier is applied outside the Reader, the transformation must be" <<
Endl;
600 Log() << kINFO <<
"implemented -- or the \"Normalise\" option is removed and Fisher retrained." <<
Endl;
645 if (coeffidx==0)
fF0 = coeff;
656 Int_t dp = fout.precision();
657 fout <<
" double fFisher0;" << std::endl;
658 fout <<
" std::vector<double> fFisherCoefficients;" << std::endl;
659 fout <<
"};" << std::endl;
660 fout <<
"" << std::endl;
661 fout <<
"inline void " << className <<
"::Initialize() " << std::endl;
662 fout <<
"{" << std::endl;
663 fout <<
" fFisher0 = " << std::setprecision(12) <<
fF0 <<
";" << std::endl;
665 fout <<
" fFisherCoefficients.push_back( " << std::setprecision(12) << (*fFisherCoeff)[ivar] <<
" );" << std::endl;
668 fout <<
" // sanity check" << std::endl;
669 fout <<
" if (fFisherCoefficients.size() != fNvars) {" << std::endl;
670 fout <<
" std::cout << \"Problem in class \\\"\" << fClassName << \"\\\"::Initialize: mismatch in number of input values\"" << std::endl;
671 fout <<
" << fFisherCoefficients.size() << \" != \" << fNvars << std::endl;" << std::endl;
672 fout <<
" fStatusIsClean = false;" << std::endl;
673 fout <<
" } " << std::endl;
674 fout <<
"}" << std::endl;
676 fout <<
"inline double " << className <<
"::GetMvaValue__( const std::vector<double>& inputValues ) const" << std::endl;
677 fout <<
"{" << std::endl;
678 fout <<
" double retval = fFisher0;" << std::endl;
679 fout <<
" for (size_t ivar = 0; ivar < fNvars; ivar++) {" << std::endl;
680 fout <<
" retval += fFisherCoefficients[ivar]*inputValues[ivar];" << std::endl;
681 fout <<
" }" << std::endl;
683 fout <<
" return retval;" << std::endl;
684 fout <<
"}" << std::endl;
686 fout <<
"// Clean up" << std::endl;
687 fout <<
"inline void " << className <<
"::Clear() " << std::endl;
688 fout <<
"{" << std::endl;
689 fout <<
" // clear coefficients" << std::endl;
690 fout <<
" fFisherCoefficients.clear(); " << std::endl;
691 fout <<
"}" << std::endl;
692 fout << std::setprecision(dp);
706 Log() <<
"Fisher discriminants select events by distinguishing the mean " <<
Endl;
707 Log() <<
"values of the signal and background distributions in a trans- " <<
Endl;
708 Log() <<
"formed variable space where linear correlations are removed." <<
Endl;
710 Log() <<
" (More precisely: the \"linear discriminator\" determines" <<
Endl;
711 Log() <<
" an axis in the (correlated) hyperspace of the input " <<
Endl;
712 Log() <<
" variables such that, when projecting the output classes " <<
Endl;
713 Log() <<
" (signal and background) upon this axis, they are pushed " <<
Endl;
714 Log() <<
" as far as possible away from each other, while events" <<
Endl;
715 Log() <<
" of a same class are confined in a close vicinity. The " <<
Endl;
716 Log() <<
" linearity property of this classifier is reflected in the " <<
Endl;
717 Log() <<
" metric with which \"far apart\" and \"close vicinity\" are " <<
Endl;
718 Log() <<
" determined: the covariance matrix of the discriminating" <<
Endl;
719 Log() <<
" variable space.)" <<
Endl;
723 Log() <<
"Optimal performance for Fisher discriminants is obtained for " <<
Endl;
724 Log() <<
"linearly correlated Gaussian-distributed variables. Any deviation" <<
Endl;
725 Log() <<
"from this ideal reduces the achievable separation power. In " <<
Endl;
726 Log() <<
"particular, no discrimination at all is achieved for a variable" <<
Endl;
727 Log() <<
"that has the same sample mean for signal and background, even if " <<
Endl;
728 Log() <<
"the shapes of the distributions are very different. Thus, Fisher " <<
Endl;
729 Log() <<
"discriminants often benefit from suitable transformations of the " <<
Endl;
730 Log() <<
"input variables. For example, if a variable x in [-1,1] has a " <<
Endl;
731 Log() <<
"a parabolic signal distributions, and a uniform background" <<
Endl;
732 Log() <<
"distributions, their mean value is zero in both cases, leading " <<
Endl;
733 Log() <<
"to no separation. The simple transformation x -> |x| renders this " <<
Endl;
734 Log() <<
"variable powerful for the use in a Fisher discriminant." <<
Endl;
#define REGISTER_METHOD(CLASS)
for example
int Int_t
Signed integer 4 bytes (int).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
TMatrixT< Double_t > TMatrixD
OptionBase * DeclareOptionRef(T &ref, const TString &name, const TString &desc="")
void AddPreDefVal(const T &)
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.
MethodBase(const TString &jobName, Types::EMVA methodType, const TString &methodTitle, DataSetInfo &dsi, const TString &theOption="")
standard constructor
const char * GetName() const override
Double_t GetXmin(Int_t ivar) const
const Event * GetEvent() const
DataSetInfo & DataInfo() const
Double_t GetXmax(Int_t ivar) const
TransformationHandler & GetTransformationHandler(Bool_t takeReroutedIfAvailable=true)
void SetSignalReferenceCut(Double_t cut)
void NoErrorCalc(Double_t *const err, Double_t *const errUpper)
const TString & GetInputLabel(Int_t i) const
Bool_t IsNormalised() const
void GetCov_Full(void)
compute full covariance matrix from sum of within and between matrices
Double_t fSumOfWeightsS
sum-of-weights for signal training events
void GetHelpMessage() const override
get help message text
TMatrixD * fBetw
between-class matrix
MethodFisher(const TString &jobName, const TString &methodTitle, DataSetInfo &dsi, const TString &theOption="Fisher")
standard constructor for the "Fisher"
TMatrixD * fCov
full covariance matrix
virtual ~MethodFisher(void)
destructor
Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets) override
Fisher can only handle classification with 2 classes.
void AddWeightsXMLTo(void *parent) const override
create XML description of Fisher classifier
void GetDiscrimPower(void)
computation of discrimination power indicator for each variable small values of "fWith" indicates lit...
TMatrixD * fWith
within-class matrix
EFisherMethod GetFisherMethod(void)
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 Init(void) override
default initialization called by all constructors
void DeclareOptions() override
MethodFisher options: format and syntax of option string: "type" where type is "Fisher" or "Mahalanob...
EFisherMethod fFisherMethod
Fisher or Mahalanobis.
std::vector< Double_t > * fFisherCoeff
Fisher coefficients.
std::vector< Double_t > * fDiscrimPow
discriminating power
void MakeClassSpecific(std::ostream &, const TString &) const override
write Fisher-specific classifier response
void ReadWeightsFromXML(void *wghtnode) override
read Fisher coefficients from xml weight file
void GetFisherCoeff(void)
Fisher = Sum { [coeff]*[variables] }.
void GetMean(void)
compute mean values of variables in each sample, and the overall means
void Train(void) override
computation of Fisher coefficients by series of matrix operations
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 ...
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
returns the Fisher value (no fixed range)
void ProcessOptions() override
process user options
TString fTheMethod
Fisher or Mahalanobis.
const Ranking * CreateRanking() override
computes ranking of input variables
Double_t fSumOfWeightsB
sum-of-weights for background training events
void ReadWeightsFromStream(std::istream &i) override
read Fisher coefficients from weight file
Ranking for variables in method (implementation).
Singleton class for Global types used by TMVA.
void Print(Option_t *name="") const override
Print the matrix as a table of elements.
Double_t Determinant() const override
Return the matrix determinant.
TMatrixT< Element > & Invert(Double_t *det=nullptr)
Invert the matrix and calculate its determinant.
create variable transformations
MsgLogger & Endl(MsgLogger &ml)
Double_t Sqrt(Double_t x)
Returns the square root of x.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
static uint64_t sum(uint64_t i)