CMS 3D CMS Logo

LossFunctions.h
Go to the documentation of this file.
1 // LossFunctions.h
2 // Here we define the different loss functions that can be used
3 // with the BDT system.
4 
5 #ifndef L1Trigger_L1TMuonEndCap_L1TLossFunctions
6 #define L1Trigger_L1TMuonEndCap_L1TLossFunctions
7 
9 #include <string>
10 #include <algorithm>
11 
12 // ========================================================
13 // ================ Define the Interface ==================
14 //=========================================================
15 
16 // Define the Interface
18 {
19  public:
20  virtual ~L1TLossFunction() =default;
21  // The gradient of the loss function.
22  // Each tree is a step in the direction of the gradient
23  // towards the minimum of the Loss Function.
24  virtual Double_t target(emtf::Event* e) = 0;
25 
26  // The fit should minimize the loss function in each
27  // terminal node at each iteration.
28  virtual Double_t fit(std::vector<emtf::Event*>& v) = 0;
29  virtual std::string name() = 0;
30  virtual int id() = 0;
31 };
32 
33 // ========================================================
34 // ================ Least Squares =========================
35 // ========================================================
36 
38 {
39  public:
42 
43  Double_t target(emtf::Event* e)
44  {
45  // Each tree fits the residuals when using LeastSquares.
46  return e->trueValue - e->predictedValue;
47  }
48 
49  Double_t fit(std::vector<emtf::Event*>& v)
50  {
51  // The average of the residuals minmizes the Loss Function for LS.
52 
53  Double_t SUM = 0;
54  for(unsigned int i=0; i<v.size(); i++)
55  {
56  emtf::Event* e = v[i];
57  SUM += e->trueValue - e->predictedValue;
58  }
59 
60  return SUM/v.size();
61  }
62  std::string name() { return "Least_Squares"; }
63  int id(){ return 1; }
64 
65 };
66 
67 // ========================================================
68 // ============== Absolute Deviation ===================
69 // ========================================================
70 
72 {
73  public:
76 
77  Double_t target(emtf::Event* e)
78  {
79  // The gradient.
80  if ((e->trueValue - e->predictedValue) >= 0)
81  return 1;
82  else
83  return -1;
84  }
85 
86  Double_t fit(std::vector<emtf::Event*>& v)
87  {
88  // The median of the residuals minimizes absolute deviation.
89  if(v.size()==0) return 0;
90  std::vector<Double_t> residuals(v.size());
91 
92  // Load the residuals into a vector.
93  for(unsigned int i=0; i<v.size(); i++)
94  {
95  emtf::Event* e = v[i];
96  residuals[i] = (e->trueValue - e->predictedValue);
97  }
98 
99  // Get the median and return it.
100  int median_loc = (residuals.size()-1)/2;
101 
102  // Odd.
103  if(residuals.size()%2 != 0)
104  {
105  std::nth_element(residuals.begin(), residuals.begin()+median_loc, residuals.end());
106  return residuals[median_loc];
107  }
108 
109  // Even.
110  else
111  {
112  std::nth_element(residuals.begin(), residuals.begin()+median_loc, residuals.end());
113  Double_t low = residuals[median_loc];
114  std::nth_element(residuals.begin()+median_loc+1, residuals.begin()+median_loc+1, residuals.end());
115  Double_t high = residuals[median_loc+1];
116  return (high + low)/2;
117  }
118  }
119  std::string name() { return "Absolute_Deviation"; }
120  int id(){ return 2; }
121 };
122 
123 // ========================================================
124 // ============== Huber ================================
125 // ========================================================
126 
127 class Huber : public L1TLossFunction
128 {
129  public:
130  Huber(){}
131  ~Huber(){}
132 
133  double quantile;
135 
136  Double_t target(emtf::Event* e)
137  {
138  // The gradient of the loss function.
139 
140  if (TMath::Abs(e->trueValue - e->predictedValue) <= quantile)
141  return (e->trueValue - e->predictedValue);
142  else
143  return quantile*(((e->trueValue - e->predictedValue) > 0)?1.0:-1.0);
144  }
145 
146  Double_t fit(std::vector<emtf::Event*>& v)
147  {
148  // The constant fit that minimizes Huber in a region.
149 
150  quantile = calculateQuantile(v, 0.7);
151  residual_median = calculateQuantile(v, 0.5);
152 
153  double x = 0;
154  for(unsigned int i=0; i<v.size(); i++)
155  {
156  emtf::Event* e = v[i];
157  double residual = e->trueValue - e->predictedValue;
158  double diff = residual - residual_median;
159  x += ((diff > 0)?1.0:-1.0)*std::min(quantile, TMath::Abs(diff));
160  }
161 
162  return (residual_median + x/v.size());
163 
164  }
165 
166  std::string name() { return "Huber"; }
167  int id(){ return 3; }
168 
169  double calculateQuantile(std::vector<emtf::Event*>& v, double whichQuantile)
170  {
171  // Container for the residuals.
172  std::vector<Double_t> residuals(v.size());
173 
174  // Load the residuals into a vector.
175  for(unsigned int i=0; i<v.size(); i++)
176  {
177  emtf::Event* e = v[i];
178  residuals[i] = TMath::Abs(e->trueValue - e->predictedValue);
179  }
180 
181  std::sort(residuals.begin(), residuals.end());
182  unsigned int quantile_location = whichQuantile*(residuals.size()-1);
183  return residuals[quantile_location];
184  }
185 };
186 
187 // ========================================================
188 // ============== Percent Error ===========================
189 // ========================================================
190 
192 {
193  public:
196 
197  Double_t target(emtf::Event* e)
198  {
199  // The gradient of the squared percent error.
200  return (e->trueValue - e->predictedValue)/(e->trueValue * e->trueValue);
201  }
202 
203  Double_t fit(std::vector<emtf::Event*>& v)
204  {
205  // The average of the weighted residuals minimizes the squared percent error.
206  // Weight(i) = 1/true(i)^2.
207 
208  Double_t SUMtop = 0;
209  Double_t SUMbottom = 0;
210 
211  for(unsigned int i=0; i<v.size(); i++)
212  {
213  emtf::Event* e = v[i];
214  SUMtop += (e->trueValue - e->predictedValue)/(e->trueValue*e->trueValue);
215  SUMbottom += 1/(e->trueValue*e->trueValue);
216  }
217 
218  return SUMtop/SUMbottom;
219  }
220  std::string name() { return "Percent_Error"; }
221  int id(){ return 4; }
222 };
223 
224 #endif
virtual std::string name()=0
double residual_median
Double_t target(emtf::Event *e)
Double_t target(emtf::Event *e)
Double_t target(emtf::Event *e)
Definition: LossFunctions.h:77
Double_t fit(std::vector< emtf::Event * > &v)
virtual ~L1TLossFunction()=default
Double_t fit(std::vector< emtf::Event * > &v)
Definition: LossFunctions.h:86
double calculateQuantile(std::vector< emtf::Event * > &v, double whichQuantile)
std::string name()
Definition: LossFunctions.h:62
virtual Double_t target(emtf::Event *e)=0
Double_t trueValue
Definition: Event.h:19
T Abs(T a)
Definition: MathUtil.h:49
Double_t target(emtf::Event *e)
Definition: LossFunctions.h:43
Double_t fit(std::vector< emtf::Event * > &v)
T min(T a, T b)
Definition: MathUtil.h:58
virtual Double_t fit(std::vector< emtf::Event * > &v)=0
virtual int id()=0
std::string name()
double quantile
Double_t predictedValue
Definition: Event.h:20
int id()
#define SUM(A, B)
Double_t fit(std::vector< emtf::Event * > &v)
Definition: LossFunctions.h:49
std::string name()
std::string name()