GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
Classifier.cpp
1 /*
2 GRT MIT License
3 Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
4 
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
6 and associated documentation files (the "Software"), to deal in the Software without restriction,
7 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all copies or substantial
12 portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 */
20 
21 #define GRT_DLL_EXPORTS
22 #include "Classifier.h"
23 
24 GRT_BEGIN_NAMESPACE
25 
26 Classifier::StringClassifierMap* Classifier::stringClassifierMap = NULL;
27 UINT Classifier::numClassifierInstances = 0;
28 
29 Classifier* Classifier::createNewInstance() const { return create(); }
30 Classifier* Classifier::createInstanceFromString(const std::string &id) { return create(id); }
31 
32 Classifier* Classifier::create(const std::string &id){
33 
34  //This function maps the input string and returns a pointer to a new instance
35 
36  StringClassifierMap::iterator iter = getMap()->find( id );
37  if( iter == getMap()->end() ){
38  //If the iterator points to the end of the map, then no match was found so return NULL
39  return NULL;
40  }
41 
42  return iter->second();
43 }
44 
46  return create( MLBase::getId() );
47 }
48 
50 
51  Classifier *newInstance = create( MLBase::getId() );
52 
53  if( newInstance == NULL ) return NULL;
54 
55  if( !newInstance->deepCopyFrom( this ) ){
56  delete newInstance;
57  return NULL;
58  }
59  return newInstance;
60 }
61 
63  return this;
64 }
65 
67  Vector< std::string > registeredClassifiers;
68 
69  StringClassifierMap::iterator iter = getMap()->begin();
70  while( iter != getMap()->end() ){
71  registeredClassifiers.push_back( iter->first );
72  ++iter; //++iter is faster than iter++ as it does not require a copy/move operator
73  }
74  return registeredClassifiers;
75 }
76 
77 Classifier::Classifier( const std::string &id ) : MLBase( id, MLBase::CLASSIFIER )
78 {
79  classifierMode = STANDARD_CLASSIFIER_MODE;
80  supportsNullRejection = false;
81  useNullRejection = false;
82  numInputDimensions = 0;
83  numOutputDimensions = 0;
84  numClasses = 0;
85  predictedClassLabel = 0;
86  maxLikelihood = 0;
87  bestDistance = 0;
88  phase = 0;
89  trainingSetAccuracy = 0;
90  nullRejectionCoeff = 5;
91  numClassifierInstances++;
92 }
93 
95  if( --numClassifierInstances == 0 ){
96  delete stringClassifierMap;
97  stringClassifierMap = NULL;
98  }
99 }
100 
102 
103  if( classifier == NULL ){
104  errorLog << "copyBaseVariables(const Classifier *classifier) - Classifier is NULL!" << std::endl;
105  return false;
106  }
107 
108  if( !this->copyMLBaseVariables( classifier ) ){
109  return false;
110  }
111 
112  this->classifierMode = classifier->classifierMode;
113  this->supportsNullRejection = classifier->supportsNullRejection;
114  this->useNullRejection = classifier->useNullRejection;
115  this->numClasses = classifier->numClasses;
116  this->predictedClassLabel = classifier->predictedClassLabel;
117  this->classifierMode = classifier->classifierMode;
118  this->nullRejectionCoeff = classifier->nullRejectionCoeff;
119  this->maxLikelihood = classifier->maxLikelihood;
120  this->bestDistance = classifier->bestDistance;
121  this->phase = classifier->phase;
122  this->trainingSetAccuracy = classifier->trainingSetAccuracy;
123  this->classLabels = classifier->classLabels;
124  this->classLikelihoods = classifier->classLikelihoods;
125  this->classDistances = classifier->classDistances;
126  this->nullRejectionThresholds = classifier->nullRejectionThresholds;
127  this->ranges = classifier->ranges;
128 
129  return true;
130 }
131 
133 
134  //Reset the base class
135  MLBase::reset();
136 
137  //Reset the classifier
138  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
139  maxLikelihood = 0;
140  bestDistance = 0;
141  phase = 0;
142  if( trained ){
143  classLikelihoods.clear();
144  classDistances.clear();
145  classLikelihoods.resize(numClasses,0);
146  classDistances.resize(numClasses,0);
147  }
148  return true;
149 }
150 
152 
153  //Clear the MLBase variables
154  MLBase::clear();
155 
156  //Clear the classifier variables
157  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
158  maxLikelihood = 0;
159  bestDistance = 0;
160  phase = 0;
161  trainingSetAccuracy = 0;
162  classLikelihoods.clear();
163  classDistances.clear();
164  nullRejectionThresholds.clear();
165  classLabels.clear();
166  ranges.clear();
167 
168  return true;
169 }
170 
171 bool Classifier::computeAccuracy( const ClassificationData &data, Float &accuracy ){
172  return Metrics::computeAccuracy( *this, data, accuracy );
173 }
174 
175 std::string Classifier::getClassifierType() const{
176  return MLBase::getId();
177 }
178 
180  return supportsNullRejection;
181 }
182 
184  return useNullRejection;
185 }
186 
188  return nullRejectionCoeff;
189 }
190 
192  if( trained ) return maxLikelihood;
194 }
195 
196 Float Classifier::getPhase() const{
197  return phase;
198 }
199 
201  return trainingSetAccuracy;
202 }
203 
205  if( trained ) return bestDistance;
206  return DEFAULT_NULL_DISTANCE_VALUE;
207 }
208 
210  return numClasses;
211 }
212 
213 UINT Classifier::getClassLabelIndexValue(const UINT classLabel) const{
214  for(UINT i=0; i<classLabels.size(); i++){
215  if( classLabel == classLabels[i] )
216  return i;
217  }
218  return 0;
219 }
220 
222  if( trained ) return predictedClassLabel;
223  return 0;
224 }
225 
227  if( trained ) return classLikelihoods;
228  return VectorFloat();
229 }
230 
232  if( trained ) return classDistances;
233  return VectorFloat();
234 }
235 
237  if( trained ) return nullRejectionThresholds;
238  return VectorFloat();
239 }
240 
242  return classLabels;
243 }
244 
246  return ranges;
247 }
248 
249 bool Classifier::enableNullRejection(const bool useNullRejection){
250  this->useNullRejection = useNullRejection;
251  return true;
252 }
253 
254 bool Classifier::setNullRejectionCoeff(const Float nullRejectionCoeff){
255  if( nullRejectionCoeff > 0 ){
256  this->nullRejectionCoeff = nullRejectionCoeff;
257  return true;
258  }
259  return false;
260 }
261 
262 bool Classifier::setNullRejectionThresholds(const VectorFloat &newRejectionThresholds){
263  if( newRejectionThresholds.getSize() == getNumClasses() ){
264  nullRejectionThresholds = newRejectionThresholds;
265  return true;
266  }
267  return false;
268 }
269 
271  return *this;
272 }
273 
274 bool Classifier::saveBaseSettingsToFile( std::fstream &file ) const{
275 
276  if( !file.is_open() ){
277  errorLog << "saveBaseSettingsToFile(fstream &file) - The file is not open!" << std::endl;
278  return false;
279  }
280 
281  if( !MLBase::saveBaseSettingsToFile( file ) ) return false;
282 
283  file << "UseNullRejection: " << useNullRejection << std::endl;
284  file << "ClassifierMode: " << classifierMode << std::endl;
285  file << "NullRejectionCoeff: " << nullRejectionCoeff << std::endl;
286 
287  if( trained ){
288 
289  file << "NumClasses: " << numClasses << std::endl;
290 
291  file << "NullRejectionThresholds: ";
292  if (useNullRejection && nullRejectionThresholds.size()){
293  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
294  file << " " << nullRejectionThresholds[i];
295  }
296  file << std::endl;
297  }else{
298  for(UINT i=0; i<numClasses; i++){
299  file << " " << 0.0;
300  }
301  file << std::endl;
302  }
303 
304  file << "ClassLabels: ";
305  for(UINT i=0; i<classLabels.size(); i++){
306  file << " " << classLabels[i];
307  }
308  file << std::endl;
309 
310  if( useScaling ){
311  file << "Ranges: " << std::endl;
312  for(UINT i=0; i<ranges.size(); i++){
313  file << ranges[i].minValue << "\t" << ranges[i].maxValue << std::endl;
314  }
315  }
316  }
317 
318  return true;
319 }
320 
321 bool Classifier::loadBaseSettingsFromFile( std::fstream &file ){
322 
323  if( !file.is_open() ){
324  errorLog << "loadBaseSettingsFromFile(fstream &file) - The file is not open!" << std::endl;
325  return false;
326  }
327 
328  //Try and load the base settings from the file
329  if( !MLBase::loadBaseSettingsFromFile( file ) ){
330  return false;
331  }
332 
333  std::string word;
334 
335  //Load if the number of clusters
336  file >> word;
337  if( word != "UseNullRejection:" ){
338  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read UseNullRejection header!" << std::endl;
339  clear();
340  return false;
341  }
342  file >> useNullRejection;
343 
344  //Load if the classifier mode
345  file >> word;
346  if( word != "ClassifierMode:" ){
347  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassifierMode header!" << std::endl;
348  clear();
349  return false;
350  }
351  file >> classifierMode;
352 
353  //Load if the null rejection coeff
354  file >> word;
355  if( word != "NullRejectionCoeff:" ){
356  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionCoeff header!" << std::endl;
357  clear();
358  return false;
359  }
360  file >> nullRejectionCoeff;
361 
362  //If the model is trained then load the model settings
363  if( trained ){
364 
365  //Load the number of classes
366  file >> word;
367  if( word != "NumClasses:" ){
368  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NumClasses header!" << std::endl;
369  clear();
370  return false;
371  }
372  file >> numClasses;
373 
374  //Load the null rejection thresholds
375  file >> word;
376  if( word != "NullRejectionThresholds:" ){
377  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionThresholds header!" << std::endl;
378  clear();
379  return false;
380  }
381  nullRejectionThresholds.resize(numClasses);
382  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
383  file >> nullRejectionThresholds[i];
384  }
385 
386  //Load the class labels
387  file >> word;
388  if( word != "ClassLabels:" ){
389  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassLabels header!" << std::endl;
390  clear();
391  return false;
392  }
393  classLabels.resize( numClasses );
394  for(UINT i=0; i<classLabels.size(); i++){
395  file >> classLabels[i];
396  }
397 
398  if( useScaling ){
399  //Load if the Ranges
400  file >> word;
401  if( word != "Ranges:" ){
402  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read Ranges header!" << std::endl;
403  clear();
404  return false;
405  }
406  ranges.resize(numInputDimensions);
407 
408  for(UINT i=0; i<ranges.size(); i++){
409  file >> ranges[i].minValue;
410  file >> ranges[i].maxValue;
411  }
412  }
413  }
414 
415  return true;
416 }
417 
418 GRT_END_NAMESPACE
419 
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: Classifier.cpp:274
bool saveBaseSettingsToFile(std::fstream &file) const
Definition: MLBase.cpp:435
std::string getId() const
Definition: GRTBase.cpp:85
#define DEFAULT_NULL_LIKELIHOOD_VALUE
Definition: Classifier.h:33
Classifier * deepCopy() const
Definition: Classifier.cpp:49
Vector< UINT > getClassLabels() const
Definition: Classifier.cpp:241
Vector< MinMax > getRanges() const
Definition: Classifier.cpp:245
virtual bool reset()
Definition: MLBase.cpp:147
VectorFloat getNullRejectionThresholds() const
Definition: Classifier.cpp:236
Classifier(const std::string &classifierId="")
Definition: Classifier.cpp:77
std::string getClassifierType() const
Definition: Classifier.cpp:175
virtual bool setNullRejectionCoeff(const Float nullRejectionCoeff)
Definition: Classifier.cpp:254
virtual UINT getNumClasses() const
Definition: Classifier.cpp:209
virtual bool resize(const unsigned int size)
Definition: Vector.h:133
const Classifier * getClassifierPointer() const
Definition: Classifier.cpp:62
static StringClassifierMap * getMap()
Definition: Classifier.h:354
UINT getSize() const
Definition: Vector.h:201
Float getNullRejectionCoeff() const
Definition: Classifier.cpp:187
virtual bool computeAccuracy(const ClassificationData &data, Float &accuracy)
Definition: Classifier.cpp:171
virtual bool deepCopyFrom(const Classifier *classifier)
Definition: Classifier.h:64
bool getSupportsNullRejection() const
Definition: Classifier.cpp:179
bool getNullRejectionEnabled() const
Definition: Classifier.cpp:183
Float getPhase() const
Definition: Classifier.cpp:196
UINT getPredictedClassLabel() const
Definition: Classifier.cpp:221
bool copyMLBaseVariables(const MLBase *mlBase)
Definition: MLBase.cpp:62
Float getBestDistance() const
Definition: Classifier.cpp:204
bool copyBaseVariables(const Classifier *classifier)
Definition: Classifier.cpp:101
virtual ~Classifier(void)
Definition: Classifier.cpp:94
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: Classifier.cpp:321
Float getMaximumLikelihood() const
Definition: Classifier.cpp:191
UINT getClassLabelIndexValue(const UINT classLabel) const
Definition: Classifier.cpp:213
bool loadBaseSettingsFromFile(std::fstream &file)
Definition: MLBase.cpp:458
virtual bool reset()
Definition: Classifier.cpp:132
virtual bool clear()
Definition: MLBase.cpp:149
VectorFloat getClassDistances() const
Definition: Classifier.cpp:231
Float getTrainingSetAccuracy() const
Definition: Classifier.cpp:200
static Vector< std::string > getRegisteredClassifiers()
Definition: Classifier.cpp:66
VectorFloat getClassLikelihoods() const
Definition: Classifier.cpp:226
std::map< std::string, Classifier *(*)() > StringClassifierMap
Definition: Classifier.h:268
Definition: Vector.h:41
bool enableNullRejection(const bool useNullRejection)
Definition: Classifier.cpp:249
virtual bool setNullRejectionThresholds(const VectorFloat &newRejectionThresholds)
Definition: Classifier.cpp:262
virtual bool clear()
Definition: Classifier.cpp:151
Classifier * create() const
Definition: Classifier.cpp:45
This is the main base class that all GRT machine learning algorithms should inherit from...
Definition: MLBase.h:72
This is the main base class that all GRT Classification algorithms should inherit from...
Definition: Classifier.h:41
static bool computeAccuracy(Classifier &model, const ClassificationData &data, Float &accuracy)
Definition: Metrics.cpp:32
const Classifier & getBaseClassifier() const
Definition: Classifier.cpp:270