GestureRecognitionToolkit  Version: 1.0 Revision: 04-03-15
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 #include "Classifier.h"
22 namespace GRT{
23 
24 Classifier::StringClassifierMap* Classifier::stringClassifierMap = NULL;
25 UINT Classifier::numClassifierInstances = 0;
26 
27 Classifier* Classifier::createInstanceFromString(string const &classifierType){
28 
29  StringClassifierMap::iterator iter = getMap()->find( classifierType );
30  if( iter == getMap()->end() ){
31  return NULL;
32  }
33  return iter->second();
34 }
36  return createInstanceFromString( classifierType );
37 }
38 
40 
41  Classifier *newInstance = createInstanceFromString( classifierType );
42 
43  if( newInstance == NULL ) return NULL;
44 
45  if( !newInstance->deepCopyFrom( this ) ){
46  delete newInstance;
47  return NULL;
48  }
49  return newInstance;
50 }
51 
53  return this;
54 }
55 
57  vector< string > registeredClassifiers;
58 
59  StringClassifierMap::iterator iter = getMap()->begin();
60  while( iter != getMap()->end() ){
61  registeredClassifiers.push_back( iter->first );
62  iter++;
63  }
64  return registeredClassifiers;
65 }
66 
68  baseType = MLBase::CLASSIFIER;
69  classifierMode = STANDARD_CLASSIFIER_MODE;
70  classifierType = "NOT_SET";
71  supportsNullRejection = false;
72  useNullRejection = false;
73  numInputDimensions = 0;
74  numOutputDimensions = 1;
75  numClasses = 0;
76  predictedClassLabel = 0;
77  maxLikelihood = 0;
78  bestDistance = 0;
79  phase = 0;
80  nullRejectionCoeff = 5;
81  numClassifierInstances++;
82 }
83 
85  if( --numClassifierInstances == 0 ){
86  delete stringClassifierMap;
87  stringClassifierMap = NULL;
88  }
89 }
90 
91 bool Classifier::copyBaseVariables(const Classifier *classifier){
92 
93  if( classifier == NULL ){
94  errorLog << "copyBaseVariables(const Classifier *classifier) - Classifier is NULL!" << endl;
95  return false;
96  }
97 
98  if( !this->copyMLBaseVariables( classifier ) ){
99  return false;
100  }
101 
102  this->classifierType = classifier->classifierType;
103  this->classifierMode = classifier->classifierMode;
104  this->supportsNullRejection = classifier->supportsNullRejection;
105  this->useNullRejection = classifier->useNullRejection;
106  this->numClasses = classifier->numClasses;
107  this->predictedClassLabel = classifier->predictedClassLabel;
108  this->nullRejectionCoeff = classifier->nullRejectionCoeff;
109  this->maxLikelihood = classifier->maxLikelihood;
110  this->bestDistance = classifier->bestDistance;
111  this->phase = classifier->phase;
112  this->classLabels = classifier->classLabels;
113  this->classLikelihoods = classifier->classLikelihoods;
114  this->classDistances = classifier->classDistances;
115  this->nullRejectionThresholds = classifier->nullRejectionThresholds;
116  this->ranges = classifier->ranges;
117 
118  return true;
119 }
120 
122 
123  //Reset the base class
124  MLBase::reset();
125 
126  //Reset the classifier
127  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
128  maxLikelihood = 0;
129  bestDistance = 0;
130  phase = 0;
131  if( trained ){
132  classLikelihoods.clear();
133  classDistances.clear();
134  classLikelihoods.resize(numClasses,0);
135  classDistances.resize(numClasses,0);
136  }
137  return true;
138 }
139 
141 
142  //Clear the MLBase variables
143  MLBase::clear();
144 
145  //Clear the classifier variables
146  predictedClassLabel = GRT_DEFAULT_NULL_CLASS_LABEL;
147  maxLikelihood = 0;
148  bestDistance = 0;
149  phase = 0;
150  classLikelihoods.clear();
151  classDistances.clear();
152  nullRejectionThresholds.clear();
153  classLabels.clear();
154  ranges.clear();
155 
156  return true;
157 }
158 
160  return classifierType;
161 }
162 
164  return supportsNullRejection;
165 }
166 
168  return useNullRejection;
169 }
170 
172  return nullRejectionCoeff;
173 }
174 
176  if( trained ) return maxLikelihood;
177  return DEFAULT_NULL_LIKELIHOOD_VALUE;
178 }
179 
180 double Classifier::getPhase() const{
181  return phase;
182 }
183 
185  if( trained ) return bestDistance;
186  return DEFAULT_NULL_DISTANCE_VALUE;
187 }
188 
190  return numClasses;
191 }
192 
193 UINT Classifier::getClassLabelIndexValue(UINT classLabel) const{
194  for(UINT i=0; i<classLabels.size(); i++){
195  if( classLabel == classLabels[i] )
196  return i;
197  }
198  return 0;
199 }
200 
202  if( trained ) return predictedClassLabel;
203  return 0;
204 }
205 
206 VectorDouble Classifier::getClassLikelihoods() const{
207  if( trained ) return classLikelihoods;
208  return VectorDouble();
209 }
210 
211 VectorDouble Classifier::getClassDistances() const{
212  if( trained ) return classDistances;
213  return VectorDouble();
214 }
215 
217  if( trained ) return nullRejectionThresholds;
218  return VectorDouble();
219 }
220 
221 vector< UINT > Classifier::getClassLabels() const{
222  return classLabels;
223 }
224 
225 vector<MinMax> Classifier::getRanges() const{
226  return ranges;
227 }
228 
229 bool Classifier::enableNullRejection(bool useNullRejection){
230  this->useNullRejection = useNullRejection;
231  return true;
232 }
233 
234 bool Classifier::setNullRejectionCoeff(double nullRejectionCoeff){
235  if( nullRejectionCoeff > 0 ){
236  this->nullRejectionCoeff = nullRejectionCoeff;
237  return true;
238  }
239  return false;
240 }
241 
242 bool Classifier::setNullRejectionThresholds(VectorDouble newRejectionThresholds){
243  if( newRejectionThresholds.size() == getNumClasses() ){
244  nullRejectionThresholds = newRejectionThresholds;
245  return true;
246  }
247  return false;
248 }
249 
251  return *this;
252 }
253 
254 bool Classifier::saveBaseSettingsToFile(fstream &file) const{
255 
256  if( !file.is_open() ){
257  errorLog << "saveBaseSettingsToFile(fstream &file) - The file is not open!" << endl;
258  return false;
259  }
260 
261  if( !MLBase::saveBaseSettingsToFile( file ) ) return false;
262 
263  file << "UseNullRejection: " << useNullRejection << endl;
264  file << "ClassifierMode: " << classifierMode << endl;
265  file << "NullRejectionCoeff: " << nullRejectionCoeff << endl;
266 
267  if( trained ){
268 
269  file << "NumClasses: " << numClasses << endl;
270 
271  file << "NullRejectionThresholds: ";
272  if (useNullRejection && nullRejectionThresholds.size()){
273  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
274  file << " " << nullRejectionThresholds[i];
275  }
276  file << endl;
277  }else{
278  for(UINT i=0; i<numClasses; i++){
279  file << " " << 0.0;
280  }
281  file << endl;
282  }
283 
284  file << "ClassLabels: ";
285  for(UINT i=0; i<classLabels.size(); i++){
286  file << " " << classLabels[i];
287  }
288  file << endl;
289 
290  if( useScaling ){
291  file << "Ranges: " << endl;
292  for(UINT i=0; i<ranges.size(); i++){
293  file << ranges[i].minValue << "\t" << ranges[i].maxValue << endl;
294  }
295  }
296  }
297 
298  return true;
299 }
300 
302 
303  if( !file.is_open() ){
304  errorLog << "loadBaseSettingsFromFile(fstream &file) - The file is not open!" << endl;
305  return false;
306  }
307 
308  //Try and load the base settings from the file
309  if( !MLBase::loadBaseSettingsFromFile( file ) ){
310  return false;
311  }
312 
313  string word;
314 
315  //Load if the number of clusters
316  file >> word;
317  if( word != "UseNullRejection:" ){
318  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read UseNullRejection header!" << endl;
319  clear();
320  return false;
321  }
322  file >> useNullRejection;
323 
324  //Load if the classifier mode
325  file >> word;
326  if( word != "ClassifierMode:" ){
327  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassifierMode header!" << endl;
328  clear();
329  return false;
330  }
331  file >> classifierMode;
332 
333  //Load if the null rejection coeff
334  file >> word;
335  if( word != "NullRejectionCoeff:" ){
336  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionCoeff header!" << endl;
337  clear();
338  return false;
339  }
340  file >> nullRejectionCoeff;
341 
342  //If the model is trained then load the model settings
343  if( trained ){
344 
345  //Load the number of classes
346  file >> word;
347  if( word != "NumClasses:" ){
348  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NumClasses header!" << endl;
349  clear();
350  return false;
351  }
352  file >> numClasses;
353 
354  //Load the null rejection thresholds
355  file >> word;
356  if( word != "NullRejectionThresholds:" ){
357  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read NullRejectionThresholds header!" << endl;
358  clear();
359  return false;
360  }
361  nullRejectionThresholds.resize(numClasses);
362  for(UINT i=0; i<nullRejectionThresholds.size(); i++){
363  file >> nullRejectionThresholds[i];
364  }
365 
366  //Load the class labels
367  file >> word;
368  if( word != "ClassLabels:" ){
369  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read ClassLabels header!" << endl;
370  clear();
371  return false;
372  }
373  classLabels.resize( numClasses );
374  for(UINT i=0; i<classLabels.size(); i++){
375  file >> classLabels[i];
376  }
377 
378  if( useScaling ){
379  //Load if the Ranges
380  file >> word;
381  if( word != "Ranges:" ){
382  errorLog << "loadBaseSettingsFromFile(fstream &file) - Failed to read Ranges header!" << endl;
383  clear();
384  return false;
385  }
386  ranges.resize(numInputDimensions);
387 
388  for(UINT i=0; i<ranges.size(); i++){
389  file >> ranges[i].minValue;
390  file >> ranges[i].maxValue;
391  }
392  }
393  }
394 
395  return true;
396 }
397 
398 } //End of namespace GRT
399 
const Classifier & getBaseClassifier() const
Definition: Classifier.cpp:250
virtual bool reset()
Definition: MLBase.cpp:116
static Classifier * createInstanceFromString(string const &classifierType)
Definition: Classifier.cpp:27
virtual bool setNullRejectionThresholds(VectorDouble newRejectionThresholds)
Definition: Classifier.cpp:242
const Classifier * getClassifierPointer() const
Definition: Classifier.cpp:52
double getPhase() const
Definition: Classifier.cpp:180
virtual bool clear()
Definition: MLBase.cpp:118
virtual bool deepCopyFrom(const Classifier *classifier)
Definition: Classifier.h:61
bool copyBaseVariables(const Classifier *classifier)
Definition: Classifier.cpp:91
std::map< string, Classifier *(*)() > StringClassifierMap
Definition: Classifier.h:248
bool loadBaseSettingsFromFile(fstream &file)
Definition: MLBase.cpp:357
Definition: AdaBoost.cpp:25
bool saveBaseSettingsToFile(fstream &file) const
Definition: MLBase.cpp:334
bool loadBaseSettingsFromFile(fstream &file)
Definition: Classifier.cpp:301
bool copyMLBaseVariables(const MLBase *mlBase)
Definition: MLBase.cpp:46
virtual UINT getNumClasses() const
Definition: Classifier.cpp:189
VectorDouble getClassLikelihoods() const
Definition: Classifier.cpp:206
Classifier * deepCopy() const
Definition: Classifier.cpp:39
VectorDouble getClassDistances() const
Definition: Classifier.cpp:211
static vector< string > getRegisteredClassifiers()
Definition: Classifier.cpp:56
double getMaximumLikelihood() const
Definition: Classifier.cpp:175
bool saveBaseSettingsToFile(fstream &file) const
Definition: Classifier.cpp:254
UINT getClassLabelIndexValue(UINT classLabel) const
Definition: Classifier.cpp:193
virtual bool reset()
Definition: Classifier.cpp:121
double getNullRejectionCoeff() const
Definition: Classifier.cpp:171
virtual ~Classifier(void)
Definition: Classifier.cpp:84
virtual bool clear()
Definition: Classifier.cpp:140
VectorDouble getNullRejectionThresholds() const
Definition: Classifier.cpp:216
bool getNullRejectionEnabled() const
Definition: Classifier.cpp:167
This is the main base class that all GRT Classification algorithms should inherit from...
double getBestDistance() const
Definition: Classifier.cpp:184
UINT getPredictedClassLabel() const
Definition: Classifier.cpp:201
Classifier * createNewInstance() const
Definition: Classifier.cpp:35
vector< MinMax > getRanges() const
Definition: Classifier.cpp:225
string getClassifierType() const
Definition: Classifier.cpp:159
bool enableNullRejection(bool useNullRejection)
Definition: Classifier.cpp:229
vector< UINT > getClassLabels() const
Definition: Classifier.cpp:221
virtual bool setNullRejectionCoeff(double nullRejectionCoeff)
Definition: Classifier.cpp:234
bool getSupportsNullRejection() const
Definition: Classifier.cpp:163