Logo ROOT   6.12/07
Reference Guide
ModulekNN.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Rustem Ospanov
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : ModulekNN *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation *
12  * *
13  * Author: *
14  * Rustem Ospanov <rustem@fnal.gov> - U. of Texas at Austin, USA *
15  * *
16  * Copyright (c) 2007: *
17  * CERN, Switzerland *
18  * MPI-K Heidelberg, Germany *
19  * U. of Texas at Austin, USA *
20  * *
21  * Redistribution and use in source and binary forms, with or without *
22  * modification, are permitted according to the terms listed in LICENSE *
23  * (http://tmva.sourceforge.net/LICENSE) *
24  **********************************************************************************/
25 
26 /*! \class TMVA::kNN
27 \ingroup TMVA
28  kNN::Event describes point in input variable vector-space, with
29  additional functionality like distance between points
30 */
31 
32 #include "TMVA/ModulekNN.h"
33 
34 #include "TMVA/MsgLogger.h"
35 #include "TMVA/Types.h"
36 
37 #include "ThreadLocalStorage.h"
38 #include "TMath.h"
39 #include "TRandom3.h"
40 
41 #include <assert.h>
42 #include <iomanip>
43 #include <iostream>
44 #include <sstream>
45 #include <algorithm>
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// default constructor
49 
51  :fVar(),
52  fWeight(-1.0),
53  fType(-1)
54 {
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// constructor
59 
60 TMVA::kNN::Event::Event(const VarVec &var, const Double_t weight, const Short_t type)
61  :fVar(var),
62  fWeight(weight),
63  fType(type)
64 {
65 }
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /// constructor
69 
70 TMVA::kNN::Event::Event(const VarVec &var, const Double_t weight, const Short_t type, const VarVec &tvec)
71  :fVar(var),
72  fTgt(tvec),
73  fWeight(weight),
74  fType(type)
75 {
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// destructor
80 
82 {
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// compute distance
87 
88 TMVA::kNN::VarType TMVA::kNN::Event::GetDist(const Event &other) const
89 {
90  const UInt_t nvar = GetNVar();
91 
92  if (nvar != other.GetNVar()) {
93  std::cerr << "Distance: two events have different dimensions" << std::endl;
94  return -1.0;
95  }
96 
97  VarType sum = 0.0;
98  for (UInt_t ivar = 0; ivar < nvar; ++ivar) {
99  sum += GetDist(other.GetVar(ivar), ivar);
100  }
101 
102  return sum;
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 
107 void TMVA::kNN::Event::SetTargets(const VarVec &tvec)
108 {
109  fTgt = tvec;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 
114 const TMVA::kNN::VarVec& TMVA::kNN::Event::GetTargets() const
115 {
116  return fTgt;
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 
121 const TMVA::kNN::VarVec& TMVA::kNN::Event::GetVars() const
122 {
123  return fVar;
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// print
128 
130 {
131  Print(std::cout);
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// print
136 
137 void TMVA::kNN::Event::Print(std::ostream& os) const
138 {
139  Int_t dp = os.precision();
140  os << "Event: ";
141  for (UInt_t ivar = 0; ivar != GetNVar(); ++ivar) {
142  if (ivar == 0) {
143  os << "(";
144  }
145  else {
146  os << ", ";
147  }
148 
149  os << std::setfill(' ') << std::setw(5) << std::setprecision(3) << GetVar(ivar);
150  }
151 
152  if (GetNVar() > 0) {
153  os << ")";
154  }
155  else {
156  os << " no variables";
157  }
158  os << std::setprecision(dp);
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// streamer
163 
164 std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& event)
165 {
166  event.Print(os);
167  return os;
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 /// default constructor
172 
174  :fDimn(0),
175  fTree(0),
176  fLogger( new MsgLogger("ModulekNN") )
177 {
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// destructor
182 
184 {
185  if (fTree) {
186  delete fTree; fTree = 0;
187  }
188  delete fLogger;
189 }
190 
191 ////////////////////////////////////////////////////////////////////////////////
192 /// clean up
193 
195 {
196  fDimn = 0;
197 
198  if (fTree) {
199  delete fTree;
200  fTree = 0;
201  }
202 
203  fVarScale.clear();
204  fCount.clear();
205  fEvent.clear();
206  fVar.clear();
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// add an event to tree
211 
213 {
214  if (fTree) {
215  Log() << kFATAL << "<Add> Cannot add event: tree is already built" << Endl;
216  return;
217  }
218 
219  if (fDimn < 1) {
220  fDimn = event.GetNVar();
221  }
222  else if (fDimn != event.GetNVar()) {
223  Log() << kFATAL << "ModulekNN::Add() - number of dimension does not match previous events" << Endl;
224  return;
225  }
226 
227  fEvent.push_back(event);
228 
229  for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
230  fVar[ivar].push_back(event.GetVar(ivar));
231  }
232 
233  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event.GetType());
234  if (cit == fCount.end()) {
235  fCount[event.GetType()] = 1;
236  }
237  else {
238  ++(cit->second);
239  }
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// fill the tree
244 
245 Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, const std::string &option)
246 {
247  if (fTree) {
248  Log() << kFATAL << "ModulekNN::Fill - tree has already been created" << Endl;
249  return kFALSE;
250  }
251 
252  // If trim option is set then find class with lowest number of events
253  // and set that as maximum number of events for all other classes.
254  UInt_t min = 0;
255  if (option.find("trim") != std::string::npos) {
256  for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
257  if (min == 0 || min > it->second) {
258  min = it->second;
259  }
260  }
261 
262  Log() << kINFO << "<Fill> Will trim all event types to " << min << " events" << Endl;
263 
264  fCount.clear();
265  fVar.clear();
266 
267  EventVec evec;
268 
269  for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
270  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
271  if (cit == fCount.end()) {
272  fCount[event->GetType()] = 1;
273  }
274  else if (cit->second < min) {
275  ++(cit->second);
276  }
277  else {
278  continue;
279  }
280 
281  for (UInt_t d = 0; d < fDimn; ++d) {
282  fVar[d].push_back(event->GetVar(d));
283  }
284 
285  evec.push_back(*event);
286  }
287 
288  Log() << kINFO << "<Fill> Erased " << fEvent.size() - evec.size() << " events" << Endl;
289 
290  fEvent = evec;
291  }
292 
293  // clear event count
294  fCount.clear();
295 
296  // sort each variable for all events - needs this before Optimize() and ComputeMetric()
297  for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
298  std::sort((it->second).begin(), (it->second).end());
299  }
300 
301  if (option.find("metric") != std::string::npos && ifrac > 0) {
302  ComputeMetric(ifrac);
303 
304  // sort again each variable for all events - needs this before Optimize()
305  // rescaling has changed variable values
306  for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
307  std::sort((it->second).begin(), (it->second).end());
308  }
309  }
310 
311  // If odepth > 0 then fill first odepth levels
312  // with empty nodes that split separating variable in half for
313  // all child nodes. If odepth = 0 then split variable 0
314  // at the median (in half) and return it as root node
315  fTree = Optimize(odepth);
316 
317  if (!fTree) {
318  Log() << kFATAL << "ModulekNN::Fill() - failed to create tree" << Endl;
319  return kFALSE;
320  }
321 
322  for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
323  fTree->Add(*event, 0);
324 
325  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
326  if (cit == fCount.end()) {
327  fCount[event->GetType()] = 1;
328  }
329  else {
330  ++(cit->second);
331  }
332  }
333 
334  for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
335  Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8)
336  << it->second << " events" << Endl;
337  }
338 
339  return kTRUE;
340 }
341 
342 ////////////////////////////////////////////////////////////////////////////////
343 /// find in tree
344 /// if tree has been filled then search for nfind closest events
345 /// if metic (fVarScale map) is computed then rescale event variables
346 /// using previously computed width of variable distribution
347 
348 Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::string &option) const
349 {
350  if (!fTree) {
351  Log() << kFATAL << "ModulekNN::Find() - tree has not been filled" << Endl;
352  return kFALSE;
353  }
354  if (fDimn != event.GetNVar()) {
355  Log() << kFATAL << "ModulekNN::Find() - number of dimension does not match training events" << Endl;
356  return kFALSE;
357  }
358  if (nfind < 1) {
359  Log() << kFATAL << "ModulekNN::Find() - requested 0 nearest neighbors" << Endl;
360  return kFALSE;
361  }
362 
363  // if variable widths are computed then rescale variable in this event
364  // to same widths as events in stored kd-tree
365  if (!fVarScale.empty()) {
366  event = Scale(event);
367  }
368 
369  // latest event for k-nearest neighbor search
370  fkNNEvent = event;
371  fkNNList.clear();
372 
373  if(option.find("weight") != std::string::npos)
374  {
375  // recursive kd-tree search for nfind-nearest neighbors
376  // use event weight to find all nearest events
377  // that have sum of weights >= nfind
378  kNN::Find<kNN::Event>(fkNNList, fTree, event, Double_t(nfind), 0.0);
379  }
380  else
381  {
382  // recursive kd-tree search for nfind-nearest neighbors
383  // count nodes and do not use event weight
384  kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);
385  }
386 
387  return kTRUE;
388 }
389 
390 ////////////////////////////////////////////////////////////////////////////////
391 /// find in tree
392 
393 Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option) const
394 {
395  if (fCount.empty() || !fTree) {
396  return kFALSE;
397  }
398  typedef std::map<Short_t, UInt_t>::const_iterator const_iterator;
399  TTHREAD_TLS_DECL_ARG(const_iterator,cit,fCount.end());
400 
401  if (cit == fCount.end()) {
402  cit = fCount.begin();
403  }
404 
405  const Short_t etype = (cit++)->first;
406 
407  if (option == "flat") {
408  VarVec dvec;
409  for (UInt_t d = 0; d < fDimn; ++d) {
410  VarMap::const_iterator vit = fVar.find(d);
411  if (vit == fVar.end()) {
412  return kFALSE;
413  }
414 
415  const std::vector<Double_t> &vvec = vit->second;
416 
417  if (vvec.empty()) {
418  return kFALSE;
419  }
420 
421  // assume that vector elements of fVar are sorted
422  const VarType min = vvec.front();
423  const VarType max = vvec.back();
424  const VarType width = max - min;
425 
426  if (width < 0.0 || width > 0.0) {
427  dvec.push_back(min + width*GetRndmThreadLocal().Rndm());
428  }
429  else {
430  return kFALSE;
431  }
432  }
433 
434  const Event event(dvec, 1.0, etype);
435 
436  Find(event, nfind);
437 
438  return kTRUE;
439  }
440 
441  return kFALSE;
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Optimize() balances binary tree for first odepth levels
446 /// for each depth we split sorted depth % dimension variables
447 /// into \f$ 2^{odepth} \f$ parts
448 
450 {
451  if (fVar.empty() || fDimn != fVar.size()) {
452  Log() << kWARNING << "<Optimize> Cannot build a tree" << Endl;
453  return 0;
454  }
455 
456  const UInt_t size = (fVar.begin()->second).size();
457  if (size < 1) {
458  Log() << kWARNING << "<Optimize> Cannot build a tree without events" << Endl;
459  return 0;
460  }
461 
462  VarMap::const_iterator it = fVar.begin();
463  for (; it != fVar.end(); ++it) {
464  if ((it->second).size() != size) {
465  Log() << kWARNING << "<Optimize> # of variables doesn't match between dimensions" << Endl;
466  return 0;
467  }
468  }
469 
470  if (double(fDimn*size) < TMath::Power(2.0, double(odepth))) {
471  Log() << kWARNING << "<Optimize> Optimization depth exceeds number of events" << Endl;
472  return 0;
473  }
474 
475  Log() << kHEADER << "Optimizing tree for " << fDimn << " variables with " << size << " values" << Endl;
476 
477  std::vector<Node<Event> *> pvec, cvec;
478 
479  it = fVar.find(0);
480  if (it == fVar.end() || (it->second).size() < 2) {
481  Log() << kWARNING << "<Optimize> Missing 0 variable" << Endl;
482  return 0;
483  }
484 
485  const Event pevent(VarVec(fDimn, (it->second)[size/2]), -1.0, -1);
486 
487  Node<Event> *tree = new Node<Event>(0, pevent, 0);
488 
489  pvec.push_back(tree);
490 
491  for (UInt_t depth = 1; depth < odepth; ++depth) {
492  const UInt_t mod = depth % fDimn;
493 
494  VarMap::const_iterator vit = fVar.find(mod);
495  if (vit == fVar.end()) {
496  Log() << kFATAL << "Missing " << mod << " variable" << Endl;
497  return 0;
498  }
499  const std::vector<Double_t> &dvec = vit->second;
500 
501  if (dvec.size() < 2) {
502  Log() << kFATAL << "Missing " << mod << " variable" << Endl;
503  return 0;
504  }
505 
506  UInt_t ichild = 1;
507  for (std::vector<Node<Event> *>::iterator pit = pvec.begin(); pit != pvec.end(); ++pit) {
508  Node<Event> *parent = *pit;
509 
510  const VarType lmedian = dvec[size*ichild/(2*pvec.size() + 1)];
511  ++ichild;
512 
513  const VarType rmedian = dvec[size*ichild/(2*pvec.size() + 1)];
514  ++ichild;
515 
516  const Event levent(VarVec(fDimn, lmedian), -1.0, -1);
517  const Event revent(VarVec(fDimn, rmedian), -1.0, -1);
518 
519  Node<Event> *lchild = new Node<Event>(parent, levent, mod);
520  Node<Event> *rchild = new Node<Event>(parent, revent, mod);
521 
522  parent->SetNodeL(lchild);
523  parent->SetNodeR(rchild);
524 
525  cvec.push_back(lchild);
526  cvec.push_back(rchild);
527  }
528 
529  pvec = cvec;
530  cvec.clear();
531  }
532 
533  return tree;
534 }
535 
536 ////////////////////////////////////////////////////////////////////////////////
537 /// compute scale factor for each variable (dimension) so that
538 /// distance is computed uniformly along each dimension
539 /// compute width of interval that includes (100 - 2*ifrac)% of events
540 /// below, assume that in fVar each vector of values is sorted
541 
543 {
544  if (ifrac == 0) {
545  return;
546  }
547  if (ifrac > 100) {
548  Log() << kFATAL << "ModulekNN::ComputeMetric - fraction can not exceed 100%" << Endl;
549  return;
550  }
551  if (!fVarScale.empty()) {
552  Log() << kFATAL << "ModulekNN::ComputeMetric - metric is already computed" << Endl;
553  return;
554  }
555  if (fEvent.size() < 100) {
556  Log() << kFATAL << "ModulekNN::ComputeMetric - number of events is too small" << Endl;
557  return;
558  }
559 
560  const UInt_t lfrac = (100 - ifrac)/2;
561  const UInt_t rfrac = 100 - (100 - ifrac)/2;
562 
563  Log() << kINFO << "Computing scale factor for 1d distributions: "
564  << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;
565 
566  fVarScale.clear();
567 
568  for (VarMap::const_iterator vit = fVar.begin(); vit != fVar.end(); ++vit) {
569  const std::vector<Double_t> &dvec = vit->second;
570 
571  std::vector<Double_t>::const_iterator beg_it = dvec.end();
572  std::vector<Double_t>::const_iterator end_it = dvec.end();
573 
574  Int_t dist = 0;
575  for (std::vector<Double_t>::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit, ++dist) {
576 
577  if ((100*dist)/dvec.size() == lfrac && beg_it == dvec.end()) {
578  beg_it = dit;
579  }
580 
581  if ((100*dist)/dvec.size() == rfrac && end_it == dvec.end()) {
582  end_it = dit;
583  }
584  }
585 
586  if (beg_it == dvec.end() || end_it == dvec.end()) {
587  beg_it = dvec.begin();
588  end_it = dvec.end();
589 
590  assert(beg_it != end_it && "Empty vector");
591 
592  --end_it;
593  }
594 
595  const Double_t lpos = *beg_it;
596  const Double_t rpos = *end_it;
597 
598  if (!(lpos < rpos)) {
599  Log() << kFATAL << "ModulekNN::ComputeMetric() - min value is greater than max value" << Endl;
600  continue;
601  }
602 
603  // Rustem: please find a solution that does not use distance (it does not exist on solaris)
604  // Log() << kINFO << "Variable " << vit->first
605  // << " included " << distance(beg_it, end_it) + 1
606  // << " events: width = " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos - lpos
607  // << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos
608  // << ", " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos << ")" << Endl;
609 
610  fVarScale[vit->first] = rpos - lpos;
611  }
612 
613  fVar.clear();
614 
615  for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {
616  fEvent[ievent] = Scale(fEvent[ievent]);
617 
618  for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
619  fVar[ivar].push_back(fEvent[ievent].GetVar(ivar));
620  }
621  }
622 }
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// scale each event variable so that rms of variables is approximately 1.0
626 /// this allows comparisons of variables with distinct scales and units
627 
629 {
630  if (fVarScale.empty()) {
631  return event;
632  }
633 
634  if (event.GetNVar() != fVarScale.size()) {
635  Log() << kFATAL << "ModulekNN::Scale() - mismatched metric and event size" << Endl;
636  return event;
637  }
638 
639  VarVec vvec(event.GetNVar(), 0.0);
640 
641  for (UInt_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
642  std::map<int, Double_t>::const_iterator fit = fVarScale.find(ivar);
643  if (fit == fVarScale.end()) {
644  Log() << kFATAL << "ModulekNN::Scale() - failed to find scale for " << ivar << Endl;
645  continue;
646  }
647 
648  if (fit->second > 0.0) {
649  vvec[ivar] = event.GetVar(ivar)/fit->second;
650  }
651  else {
652  Log() << kFATAL << "Variable " << ivar << " has zero width" << Endl;
653  }
654  }
655 
656  return Event(vvec, event.GetWeight(), event.GetType(), event.GetTargets());
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// print
661 
663 {
664  Print(std::cout);
665 }
666 
667 ////////////////////////////////////////////////////////////////////////////////
668 /// print
669 
670 void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
671 {
672  os << "----------------------------------------------------------------------"<< std::endl;
673  os << "Printing knn result" << std::endl;
674  os << fkNNEvent << std::endl;
675 
676  UInt_t count = 0;
677 
678  std::map<Short_t, Double_t> min, max;
679 
680  os << "Printing " << fkNNList.size() << " nearest neighbors" << std::endl;
681  for (List::const_iterator it = fkNNList.begin(); it != fkNNList.end(); ++it) {
682  os << ++count << ": " << it->second << ": " << it->first->GetEvent() << std::endl;
683 
684  const Event &event = it->first->GetEvent();
685  for (UShort_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
686  if (min.find(ivar) == min.end()) {
687  min[ivar] = event.GetVar(ivar);
688  }
689  else if (min[ivar] > event.GetVar(ivar)) {
690  min[ivar] = event.GetVar(ivar);
691  }
692 
693  if (max.find(ivar) == max.end()) {
694  max[ivar] = event.GetVar(ivar);
695  }
696  else if (max[ivar] < event.GetVar(ivar)) {
697  max[ivar] = event.GetVar(ivar);
698  }
699  }
700  }
701 
702  if (min.size() == max.size()) {
703  for (std::map<Short_t, Double_t>::const_iterator mit = min.begin(); mit != min.end(); ++mit) {
704  const Short_t i = mit->first;
705  Log() << kINFO << "(var, min, max) = (" << i << "," << min[i] << ", " << max[i] << ")" << Endl;
706  }
707  }
708 
709  os << "----------------------------------------------------------------------" << std::endl;
710 }
Event()
default constructor
Definition: ModulekNN.cxx:50
~ModulekNN()
destructor
Definition: ModulekNN.cxx:183
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static long int sum(long int i)
Definition: Factory.cxx:2173
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:158
ModulekNN()
default constructor
Definition: ModulekNN.cxx:173
void Print() const
print
Definition: ModulekNN.cxx:662
unsigned short UShort_t
Definition: RtypesCore.h:36
This file contains binary tree and global function template that searches tree for k-nearest neigbors...
Definition: NodekNN.h:66
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Bool_t Find(Event event, UInt_t nfind=100, const std::string &option="count") const
find in tree if tree has been filled then search for nfind closest events if metic (fVarScale map) is...
Definition: ModulekNN.cxx:348
VarType GetVar(UInt_t i) const
Definition: ModulekNN.h:179
Double_t GetWeight() const
Definition: ModulekNN.h:175
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:627
std::map< Int_t, Double_t > fVarScale
Definition: ModulekNN.h:153
MsgLogger & Log() const
Definition: ModulekNN.h:164
Short_t GetType() const
Definition: ModulekNN.h:196
const VarVec & GetTargets() const
Definition: ModulekNN.cxx:114
Double_t fWeight
Definition: ModulekNN.h:93
const Event Scale(const Event &event) const
scale each event variable so that rms of variables is approximately 1.0 this allows comparisons of va...
Definition: ModulekNN.cxx:628
void SetTargets(const VarVec &tvec)
Definition: ModulekNN.cxx:107
Bool_t Fill(const UShort_t odepth, UInt_t ifrac, const std::string &option="")
fill the tree
Definition: ModulekNN.cxx:245
void SetNodeL(Node *node)
Definition: NodekNN.h:144
VarType GetDist(VarType var, UInt_t ivar) const
Definition: ModulekNN.h:170
UInt_t GetNVar() const
Definition: ModulekNN.h:188
unsigned int UInt_t
Definition: RtypesCore.h:42
short Short_t
Definition: RtypesCore.h:35
void Add(const Event &event)
add an event to tree
Definition: ModulekNN.cxx:212
const Bool_t kFALSE
Definition: RtypesCore.h:88
PyObject * fType
double Double_t
Definition: RtypesCore.h:55
std::ostream & operator<<(std::ostream &os, const Event &event)
int type
Definition: TGX11.cxx:120
static TRandom3 & GetRndmThreadLocal()
Definition: ModulekNN.h:147
ostringstream derivative to redirect and format output
Definition: MsgLogger.h:59
MsgLogger * fLogger
Definition: ModulekNN.h:163
const VarVec & GetVars() const
Definition: ModulekNN.cxx:121
Short_t fType
Definition: ModulekNN.h:94
void Print() const
print
Definition: ModulekNN.cxx:129
std::map< Short_t, UInt_t > fCount
Definition: ModulekNN.h:158
Node< Event > * Optimize(UInt_t optimize_depth)
Optimize() balances binary tree for first odepth levels for each depth we split sorted depth % dimens...
Definition: ModulekNN.cxx:449
void Clear()
clean up
Definition: ModulekNN.cxx:194
void SetNodeR(Node *node)
Definition: NodekNN.h:150
Definition: tree.py:1
Definition: first.py:1
Node< Event > * fTree
Definition: ModulekNN.h:151
const Bool_t kTRUE
Definition: RtypesCore.h:87
void ComputeMetric(UInt_t ifrac)
compute scale factor for each variable (dimension) so that distance is computed uniformly along each ...
Definition: ModulekNN.cxx:542
~Event()
destructor
Definition: ModulekNN.cxx:81