107 if (fModule)
delete fModule;
125 DeclareOptionRef(fnkNN = 20,
"nkNN",
"Number of k-nearest neighbors");
126 DeclareOptionRef(fBalanceDepth = 6,
"BalanceDepth",
"Binary tree balance depth");
127 DeclareOptionRef(fScaleFrac = 0.80,
"ScaleFrac",
"Fraction of events used to compute variable width");
128 DeclareOptionRef(fSigmaFact = 1.0,
"SigmaFact",
"Scale factor for sigma in Gaussian kernel");
129 DeclareOptionRef(fKernel =
"Gaus",
"Kernel",
"Use polynomial (=Poln) or Gaussian (=Gaus) kernel");
130 DeclareOptionRef(fTrim =
kFALSE,
"Trim",
"Use equal number of signal and background events");
131 DeclareOptionRef(fUseKernel =
kFALSE,
"UseKernel",
"Use polynomial kernel weight");
132 DeclareOptionRef(fUseWeight =
kTRUE,
"UseWeight",
"Use weight to count kNN events");
133 DeclareOptionRef(fUseLDA =
kFALSE,
"UseLDA",
"Use local linear discriminant - experimental feature");
141 DeclareOptionRef(fTreeOptDepth = 6,
"TreeOptDepth",
"Binary tree optimisation depth");
151 Log() << kWARNING <<
"kNN must be a positive integer: set kNN = " << fnkNN <<
Endl;
153 if (fScaleFrac < 0.0) {
155 Log() << kWARNING <<
"ScaleFrac can not be negative: set ScaleFrac = " << fScaleFrac <<
Endl;
157 if (fScaleFrac > 1.0) {
160 if (!(fBalanceDepth > 0)) {
162 Log() << kWARNING <<
"Optimize must be a positive integer: set Optimize = " << fBalanceDepth <<
Endl;
167 <<
" kNN = \n" << fnkNN
168 <<
" UseKernel = \n" << fUseKernel
169 <<
" SigmaFact = \n" << fSigmaFact
170 <<
" ScaleFrac = \n" << fScaleFrac
171 <<
" Kernel = \n" << fKernel
172 <<
" Trim = \n" << fTrim
173 <<
" Optimize = " << fBalanceDepth <<
Endl;
205 Log() << kFATAL <<
"ModulekNN is not created" <<
Endl;
211 if (fScaleFrac > 0.0) {
218 Log() << kINFO <<
"Creating kd-tree with " << fEvent.size() <<
" events" <<
Endl;
220 for (kNN::EventVec::const_iterator event = fEvent.begin();
event != fEvent.end(); ++event) {
221 fModule->Add(*event);
225 fModule->Fill(
static_cast<UInt_t>(fBalanceDepth),
226 static_cast<UInt_t>(100.0*fScaleFrac),
235 Log() << kHEADER <<
"<Train> start..." <<
Endl;
237 if (IsNormalised()) {
238 Log() << kINFO <<
"Input events are normalized - setting ScaleFrac to 0" <<
Endl;
242 if (!fEvent.empty()) {
243 Log() << kINFO <<
"Erasing " << fEvent.size() <<
" previously stored events" <<
Endl;
246 if (GetNVariables() < 1)
247 Log() << kFATAL <<
"MethodKNN::Train() - mismatched or wrong number of event variables" <<
Endl;
250 Log() << kINFO <<
"Reading " << GetNEvents() <<
" events" <<
Endl;
258 if (IgnoreEventsWithNegWeightsInTraining() && weight <= 0)
continue;
265 if (DataInfo().IsSignal(
evt_)) {
266 fSumOfWeightsS += weight;
270 fSumOfWeightsB += weight;
283 <<
"Number of signal events " << fSumOfWeightsS <<
Endl
284 <<
"Number of background events " << fSumOfWeightsB <<
Endl;
303 const Int_t nvar = GetNVariables();
319 const kNN::List &rlist = fModule->GetkNNList();
320 if (rlist.size() !=
knn + 2) {
321 Log() << kFATAL <<
"kNN result list is empty" <<
Endl;
332 if (fKernel ==
"Gaus")
use_gaus =
true;
333 else if (fKernel ==
"Poln")
use_poln =
true;
344 Log() << kFATAL <<
"kNN radius is not positive" <<
Endl;
359 Log() << kFATAL <<
"Failed to compute RMS vector" <<
Endl;
367 for (kNN::List::const_iterator
lit = rlist.begin();
lit != rlist.end(); ++
lit) {
374 if (
lit->second < 0.0) {
375 Log() << kFATAL <<
"A neighbor has negative distance to query event" <<
Endl;
377 else if (!(
lit->second > 0.0)) {
378 Log() << kVERBOSE <<
"A neighbor has zero distance to query event" <<
Endl;
389 if (node.
GetEvent().GetType() == 1) {
393 else if (node.
GetEvent().GetType() == 2) {
396 Log() << kFATAL <<
"Unknown type for training event" <<
Endl;
409 Log() << kFATAL <<
"Size kNN result list is not positive" <<
Endl;
415 Log() << kDEBUG <<
"count_all and kNN have different size: " <<
count_all <<
" < " <<
knn <<
Endl;
420 Log() << kFATAL <<
"kNN result total weight is not positive" <<
Endl;
433 if( fRegressionReturnVal == 0 )
434 fRegressionReturnVal =
new std::vector<Float_t>;
436 fRegressionReturnVal->clear();
442 const Int_t nvar = GetNVariables();
458 const kNN::List &rlist = fModule->GetkNNList();
459 if (rlist.size() !=
knn + 2) {
460 Log() << kFATAL <<
"kNN result list is empty" <<
Endl;
461 return *fRegressionReturnVal;
468 for (kNN::List::const_iterator
lit = rlist.begin();
lit != rlist.end(); ++
lit) {
497 Log() << kFATAL <<
"Total weight sum is not positive: " <<
weight_all <<
Endl;
498 return *fRegressionReturnVal;
508 return *fRegressionReturnVal;
528 for (kNN::EventVec::const_iterator event = fEvent.begin();
event != fEvent.end(); ++event) {
530 std::stringstream s(
"");
533 if (
ivar>0) s <<
" ";
534 s << std::scientific <<
event->GetVar(
ivar);
538 s <<
" " << std::scientific <<
event->GetTgt(
itgt);
566 std::stringstream s(
gTools().GetContent(ch) );
589 Log() << kINFO <<
"Starting ReadWeightsFromStream(std::istream& is) function..." <<
Endl;
591 if (!fEvent.empty()) {
592 Log() << kINFO <<
"Erasing " << fEvent.size() <<
" previously stored events" <<
Endl;
602 if (
line.empty() ||
line.find(
"#") != std::string::npos) {
607 std::string::size_type pos=0;
608 while( (pos=
line.find(
',',pos)) != std::string::npos ) { count++; pos++; }
613 if (count < 3 || nvar != count - 2) {
614 Log() << kFATAL <<
"Missing comma delimeter(s)" <<
Endl;
624 std::string::size_type prev = 0;
631 if (!(
ipos > prev)) {
632 Log() << kFATAL <<
"Wrong substring limits" <<
Endl;
641 Log() << kFATAL <<
"Failed to parse string" <<
Endl;
651 weight = std::atof(
vstring.c_str());
657 Log() << kFATAL <<
"Wrong variable count" <<
Endl;
667 Log() << kINFO <<
"Read " << fEvent.size() <<
" events from text file" <<
Endl;
678 Log() << kINFO <<
"Starting WriteWeightsToStream(TFile &rf) function..." <<
Endl;
680 if (fEvent.empty()) {
681 Log() << kWARNING <<
"MethodKNN contains no events " <<
Endl;
688 tree->
Branch(
"event",
"TMVA::kNN::Event", &event);
691 for (kNN::EventVec::const_iterator it = fEvent.begin(); it != fEvent.end(); ++it) {
697 rf.WriteTObject(tree,
"knn",
"Overwrite");
702 Log() << kINFO <<
"Wrote " <<
size <<
"MB and " << fEvent.size()
703 <<
" events to ROOT file" <<
Endl;
714 Log() << kINFO <<
"Starting ReadWeightsFromStream(TFile &rf) function..." <<
Endl;
716 if (!fEvent.empty()) {
717 Log() << kINFO <<
"Erasing " << fEvent.size() <<
" previously stored events" <<
Endl;
724 Log() << kFATAL <<
"Failed to find knn tree" <<
Endl;
734 for (
Int_t i = 0; i < nevent; ++i) {
736 fEvent.push_back(*event);
742 Log() << kINFO <<
"Read " <<
size <<
"MB and " << fEvent.size()
743 <<
" events from ROOT file" <<
Endl;
756 fout <<
" // not implemented for class: \"" << className <<
"\"" << std::endl;
757 fout <<
"};" << std::endl;
771 Log() <<
"The k-nearest neighbor (k-NN) algorithm is a multi-dimensional classification" <<
Endl
772 <<
"and regression algorithm. Similarly to other TMVA algorithms, k-NN uses a set of" <<
Endl
773 <<
"training events for which a classification category/regression target is known. " <<
Endl
774 <<
"The k-NN method compares a test event to all training events using a distance " <<
Endl
775 <<
"function, which is an Euclidean distance in a space defined by the input variables. "<<
Endl
776 <<
"The k-NN method, as implemented in TMVA, uses a kd-tree algorithm to perform a" <<
Endl
777 <<
"quick search for the k events with shortest distance to the test event. The method" <<
Endl
778 <<
"returns a fraction of signal events among the k neighbors. It is recommended" <<
Endl
779 <<
"that a histogram which stores the k-NN decision variable is binned with k+1 bins" <<
Endl
780 <<
"between 0 and 1." <<
Endl;
783 Log() <<
gTools().
Color(
"bold") <<
"--- Performance tuning via configuration options: "
786 Log() <<
"The k-NN method estimates a density of signal and background events in a "<<
Endl
787 <<
"neighborhood around the test event. The method assumes that the density of the " <<
Endl
788 <<
"signal and background events is uniform and constant within the neighborhood. " <<
Endl
789 <<
"k is an adjustable parameter and it determines an average size of the " <<
Endl
790 <<
"neighborhood. Small k values (less than 10) are sensitive to statistical " <<
Endl
791 <<
"fluctuations and large (greater than 100) values might not sufficiently capture " <<
Endl
792 <<
"local differences between events in the training set. The speed of the k-NN" <<
Endl
793 <<
"method also increases with larger values of k. " <<
Endl;
795 Log() <<
"The k-NN method assigns equal weight to all input variables. Different scales " <<
Endl
796 <<
"among the input variables is compensated using ScaleFrac parameter: the input " <<
Endl
797 <<
"variables are scaled so that the widths for central ScaleFrac*100% events are " <<
Endl
798 <<
"equal among all the input variables." <<
Endl;
801 Log() <<
gTools().
Color(
"bold") <<
"--- Additional configuration options: "
804 Log() <<
"The method inclues an option to use a Gaussian kernel to smooth out the k-NN" <<
Endl
805 <<
"response. The kernel re-weights events using a distance to the test event." <<
Endl;
821 return (prod * prod * prod);
831 Log() << kFATAL <<
"Mismatched vectors in Gaussian kernel function" <<
Endl;
844 if (!(
sigm_ > 0.0)) {
845 Log() << kFATAL <<
"Bad sigma value = " <<
sigm_ <<
Endl;
871 for (kNN::List::const_iterator
lit = rlist.begin();
lit != rlist.end(); ++
lit)
873 if (!(
lit->second > 0.0))
continue;
891 std::vector<Double_t>
rvec;
895 for (kNN::List::const_iterator
lit = rlist.begin();
lit != rlist.end(); ++
lit)
897 if (!(
lit->second > 0.0))
continue;
906 Log() << kFATAL <<
"Wrong number of variables, should never happen!" <<
Endl;
921 Log() << kFATAL <<
"Bad event kcount = " <<
kcount <<
Endl;
928 Log() << kFATAL <<
"Bad RMS value = " <<
rvec[
ivar] <<
Endl;
945 for (kNN::List::const_iterator
lit = rlist.begin();
lit != rlist.end(); ++
lit) {
951 if (node.
GetEvent().GetType() == 1) {
954 else if (node.
GetEvent().GetType() == 2) {
958 Log() << kFATAL <<
"Unknown type for training event" <<
Endl;
964 return fLDA.GetProb(
event_knn.GetVars(), 1);
#define REGISTER_METHOD(CLASS)
for example
std::vector< std::vector< Float_t > > LDAEvents
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
short Short_t
Signed Short integer 2 bytes (short)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
const_iterator begin() const
const_iterator end() const
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Class that contains all the data information.
Virtual base Class for all MVA method.
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
Analysis of k-nearest neighbor.
void MakeKNN(void)
create kNN
virtual ~MethodKNN(void)
destructor
const std::vector< Double_t > getRMS(const kNN::List &rlist, const kNN::Event &event_knn) const
Get polynomial kernel radius.
const Ranking * CreateRanking() override
no ranking available
void DeclareOptions() override
MethodKNN options.
MethodKNN(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption="KNN")
standard constructor
Double_t getKernelRadius(const kNN::List &rlist) const
Get polynomial kernel radius.
void Train(void) override
kNN training
double getLDAValue(const kNN::List &rlist, const kNN::Event &event_knn)
void ProcessOptions() override
process the options specified by the user
Double_t PolnKernel(Double_t value) const
polynomial kernel
void DeclareCompatibilityOptions() override
options that are used ONLY for the READER to ensure backward compatibility
void ReadWeightsFromStream(std::istream &istr) override
read the weights
void GetHelpMessage() const override
get help message text
void MakeClassSpecific(std::ostream &, const TString &) const override
write specific classifier response
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
Compute classifier response.
Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets) override
FDA can handle classification with 2 classes and regression with one regression-target.
void Init(void) override
Initialization.
void WriteWeightsToStream(TFile &rf) const
save weights to ROOT file
Double_t GausKernel(const kNN::Event &event_knn, const kNN::Event &event, const std::vector< Double_t > &svec) const
Gaussian kernel.
void ReadWeightsFromXML(void *wghtnode) override
const std::vector< Float_t > & GetRegressionValues() override
Return vector of averages for target values of k-nearest neighbors.
void AddWeightsXMLTo(void *parent) const override
write weights to XML
Ranking for variables in method (implementation)
Singleton class for Global types used by TMVA.
This file contains binary tree and global function template that searches tree for k-nearest neigbors...
Double_t GetWeight() const
const T & GetEvent() const
std::vector< VarType > VarVec
virtual void Clear(Option_t *="")
A TTree represents a columnar dataset.
virtual Int_t Fill()
Fill all branches.
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr, TClass *realClass, EDataType datatype, bool isptr, bool suppressMissingBranchError)
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
virtual void SetDirectory(TDirectory *dir)
Change the tree's directory.
virtual Long64_t GetEntries() const
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
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.