KSquare Utilities
ClassProb.cpp
Go to the documentation of this file.
1 #include "FirstIncludes.h"
2 #include <algorithm>
3 #include <iostream>
4 #include <ostream>
5 #include <stdio.h>
6 #include "MemoryDebug.h"
7 using namespace std;
8 
10 #include "KKBaseTypes.h"
11 #include "KKException.h"
12 #include "KKStrParser.h"
13 #include "OSservices.h"
14 using namespace KKB;
15 
16 
17 #include "ClassProb.h"
18 #include "MLClass.h"
19 using namespace KKMLL;
20 
21 
22 ClassProb::ClassProb (MLClassPtr _classLabel,
23  double _probability,
24  float _votes
25  ):
26  classLabel (_classLabel),
27  probability (_probability),
28  votes (_votes)
29 {
30 }
31 
32 
33 ClassProb::ClassProb (const ClassProb& _pair):
34  classLabel (_pair.classLabel),
36  votes (_pair.votes)
37 {
38 }
39 
40 
41 
43  KKQueue<ClassProb> (true)
44 {
45 }
46 
47 
50 {
51 }
52 
53 
54 
57 {
58  for (auto idx: pairList)
59  {
60  if (Owner ())
61  PushOnBack (new ClassProb (*idx));
62  else
63  PushOnBack (idx);
64  }
65 }
66 
67 
69 {
70  return ((kkint32)size ()) * sizeof(ClassProb);
71 } /* MemoryConsumedEstimated */
72 
73 
74 
75 
76 bool ClassProbList::CompairByClassName (const ClassProbPtr left,
77  const ClassProbPtr right
78  )
79 {
81 }
82 
83 
85 {
86  sort (begin (), end (), CompairByClassName);
87 }
88 
89 
91 {
92 public:
93  ProbabilityComparer (bool _highToLow): highToLow (_highToLow) {}
94 
95  bool operator () (const ClassProbPtr left,
96  const ClassProbPtr right
97  )
98  {
99  if (highToLow)
100  return (left->probability > right->probability);
101  else
102  return (left->probability < right->probability);
103  }
104 
105 private:
106  bool highToLow;
107 }; /* ProbabilityComparer */
108 
109 
110 
112 {
113 public:
114  VotesComparer (bool _highToLow): highToLow (_highToLow) {}
115 
116  bool operator () (const ClassProbPtr left,
117  const ClassProbPtr right
118  )
119  {
120  if (left->votes == right->votes)
121  {
122  if (highToLow)
123  return (left->probability > right->probability);
124  else
125  return (left->probability < right->probability);
126  }
127  else
128  {
129  if (highToLow)
130  return (left->votes > right->votes);
131  else
132  return (left->votes < right->votes);
133  }
134  }
135 
136 private:
137  bool highToLow;
138 }; /* VotesComparer */
139 
140 
141 
142 
143 void ClassProbList::SortByProbability (bool highToLow)
144 {
145  ProbabilityComparer comparator (highToLow);
146  sort (begin (), end (), comparator);
147 } /* SortByProbability */
148 
149 
150 
151 void ClassProbList::SortByVotes (bool highToLow)
152 {
153  VotesComparer comparator (highToLow);
154  sort (begin (), end (), comparator);
155 } /* SortByVotes */
156 
157 
158 
159 
160 const ClassProbPtr ClassProbList::LookUp (MLClassPtr targetClass) const
161 {
162  MLClassIndexType::const_iterator idx;
163  idx = classIndex.find (targetClass);
164  if (idx == classIndex.end ())
165  return NULL;
166  else
167  return idx->second;
168 
169 } /* LookUp */
170 
171 
172 
173 
174 kkint32 ClassProbList::LookUpPlace (MLClassPtr targetClass) const
175 {
176  for (kkint32 x = 0; x < (kkint32)size (); ++x)
177  {
178  if (IdxToPtr (x)->classLabel == targetClass)
179  return x;
180  }
181 
182  return -1;
183 } /* LookUpPlace */
184 
185 
186 
187 void ClassProbList::DeleteEntry (ClassProbPtr cp)
188 {
189  MLClassIndexType::const_iterator idx;
190  idx = classIndex.find (cp->classLabel);
191  if (idx != classIndex.end ())
192  classIndex.erase (idx);
193  KKQueue<ClassProb>::DeleteEntry (cp);
194 }
195 
196 
197 
199 {
200  if (idx >= size ())
201  {
202  KKStr errMsg = "ClassProbList::DeleteEntry ***ERROR*** idx [" + StrFormatInt (idx, "#,###,##0") + "]";
203  cerr << endl << errMsg << endl << endl;
204  throw KKException (errMsg);
205  }
206  DeleteEntry (IdxToPtr (idx));
207 }
208 
209 
210 
211 
212 void ClassProbList::PushOnBack (ClassProbPtr cp)
213 {
214  try
215  {
216  classIndex.insert (MLClassIndexPair (cp->classLabel, cp));
217  }
218  catch (const std::exception&)
219  {
220  KKStr errMsg = "ClassProbList::PushOnBack ***ERROR*** Exception occurred adding Class[" + cp->classLabel->Name () + "]";
221  cerr << errMsg << endl;
222  throw KKException (errMsg);
223  }
224  KKQueue<ClassProb>::PushOnBack (cp);
225 }
226 
227 
228 
229 void ClassProbList::PushOnFront (ClassProbPtr cp)
230 {
231  try
232  {
233  classIndex.insert (MLClassIndexPair (cp->classLabel, cp));
234  }
235  catch (const std::exception&)
236  {
237  KKStr errMsg = "ClassProbList::PushOnFront ***ERROR*** Exception occurred adding Class[" + cp->classLabel->Name () + "]";
238  cerr << errMsg << endl;
239  throw KKException (errMsg);
240  }
241  KKQueue<ClassProb>::PushOnFront (cp);
242 }
243 
244 
245 
246 void ClassProbList::AddIn (const ClassProbListPtr otherPredictions)
247 {
248  if (!otherPredictions)
249  return;
250 
251  ClassProbList::const_iterator idx;
252  for (idx = otherPredictions->begin (); idx != otherPredictions->end (); ++idx)
253  {
254  const ClassProbPtr otherPrediction = *idx;
255  MergeIn (otherPrediction);
256  }
257 } /* AddIn */
258 
259 
260 
261 
262 /**
263  *@brief Adds the Prediction in 'cp' into this list.
264  *@details If the class indicated by 'cp->classLabel' already exist in this
265  * list will then add to existing entry otherwise will create a new entry for
266  * the class.
267  */
268 void ClassProbList::MergeIn (const ClassProbPtr cp)
269 {
271 } /* MergeIn */
272 
273 
274 
275 
276 void ClassProbList::MergeIn (MLClassPtr target,
277  double probability,
278  float votes
279  )
280 {
281  ClassProbPtr existingEntry = LookUp (target);
282  if (existingEntry)
283  {
284  existingEntry->probability += probability;
285  existingEntry->votes += votes;
286  }
287  else
288  {
289  PushOnBack (new ClassProb (target, probability, votes));
290  }
291 } /* MergeIn */
292 
293 
294 
295 
296 /**
297  *@brief Merges in the predictions in 'subPredictions' by replacing the entry in our list with
298  * label 'target' with contents of 'subPredictions'.
299  *@details It is assumed that the sum of probabilities of 'subPredictions' is equal to 1.0.
300  */
301 void ClassProbList::MergeIn (MLClassPtr target,
302  const ClassProbListPtr subPredictions
303  )
304 {
305  ClassProbPtr existingEntry = LookUp (target);
306  if (existingEntry)
307  {
308  DeleteEntry (existingEntry);
309  float totalSubVotes = (float)(subPredictions->size () - 1);
310  double baseProb = existingEntry->probability;
311  float baseVotes = existingEntry->votes;
312  ClassProbList::const_iterator idx;
313  for (idx = subPredictions->begin (); idx != subPredictions->end (); ++idx)
314  {
315  const ClassProbPtr subPrediction = *idx;
316  double subProbability = baseProb * subPrediction->probability;
317  float subVotes = baseVotes * (subPrediction->votes / totalSubVotes);
318  MergeIn (subPrediction->classLabel, subProbability, subVotes);
319  }
320  }
321  else
322  {
323  ClassProbList::const_iterator idx;
324  for (idx = subPredictions->begin (); idx != subPredictions->end (); ++idx)
325  {
326  const ClassProbPtr subPrediction = *idx;
327  MergeIn (subPrediction->classLabel, subPrediction->probability, subPrediction->votes);
328  }
329  }
330 } /* MergeIn */
331 
332 
333 
334 
335 
337 {
338  double totalProb = 0.0;
339  float totalVotes = 0.0f;
340 
341  float expectedTotalNumOfVotes = (float)(size () * (size () - 1) / 2);
342 
343  iterator idx;
344  for (idx = begin (); idx != end (); ++idx)
345  {
346  ClassProbPtr cp = *idx;
347  totalProb += cp->probability;
348  totalVotes += cp->votes;
349  }
350 
351  for (idx = begin (); idx != end (); ++idx)
352  {
353  ClassProbPtr cp = *idx;
354  cp->probability = cp->probability / totalProb;
355  cp->votes = (cp->votes / totalVotes) * expectedTotalNumOfVotes;
356  }
357 } /* NormalizeToOne */
358 
359 
360 
361 
362 ClassProbListPtr ClassProbList::CreateFromXMLStream (istream& i)
363 {
364  ClassProbListPtr result = new ClassProbList (true);
365 
366  bool eof = false;
367 
368  KKStr line = osReadRestOfLine2 (i, eof);
369 
370  while (!eof)
371  {
372  if (line.StartsWith ("</ClassProbList>"))
373  break;
374 
375  if (line.StartsWith ("<ClassProbList"))
376  continue;
377 
378  KKStr className = line.ExtractToken2 ("\n\r\t");
379  double prob = line.ExtractTokenDouble ("\t\n\r");
380  double votes = line.ExtractTokenDouble ("\t\n\r");
381  if (!className.Empty ())
382  {
383  MLClassPtr c = MLClass::CreateNewMLClass (className, -1);
384 
385  result->PushOnBack (new ClassProb (c, prob, (float)votes));
386  }
387  line = osReadRestOfLine2 (i, eof);
388  }
389 
390  return result;
391 } /* CreateFromXMLStream */
392 
393 
394 
395 
396 
397 
398 
399 
400 void ClassProbList::WriteXML (const KKStr& varName,
401  ostream& o
402  ) const
403 {
404  XmlTag startTag ("ClassProbList", XmlTag::TagTypes::tagStart);
405  if (!varName.Empty ())
406  startTag.AddAtribute ("VarName", varName);
407  startTag.WriteXML (o);
408  o << endl;
409 
410  for (auto idx: *this)
411  {
412  ClassProbPtr cp = idx;
413  o << cp->classLabel->Name () << "\t" << cp->probability << "\t" << cp->votes << endl;
414  }
415 
416  XmlTag endTag ("ClassProbList", XmlTag::TagTypes::tagEnd);
417  endTag.WriteXML (o);
418  o << endl;
419 } /* WriteXML */
420 
421 
422 
424  XmlTagConstPtr tag,
425  VolConstBool& cancelFlag,
426  RunLog& log
427  )
428 {
429  XmlTokenPtr t = NULL;
430  while (true && (!cancelFlag))
431  {
432  delete t;
433  t = s.GetNextToken (cancelFlag, log);
434  if (!t) break;
435  if (typeid (*t) != typeid (XmlContent))
436  continue;
437  XmlContentPtr content = dynamic_cast<XmlContentPtr> (t);
438  if ((content == NULL) || (content->Content () == NULL) || (content->Content ()->Empty ()))
439  continue;
440 
441  KKStrParser p (*(content->Content ()));
442  p.TrimWhiteSpace (" ");
443  KKStr className = p.GetNextToken ("\t");
444  double probability = p.GetNextTokenDouble ("\t");
445  float votes = p.GetNextTokenFloat ("\t");
446  if (className.Empty ())
447  continue;
448 
449  if ((probability < 0.0f) || (probability > 1.0f))
450  {
451  log.Level (-1)
452  << "ClassProbList::ReadXML ***ERROR*** Probability: " << probability << " is out of range for Class: " << className << endl
453  << endl;
454  }
455 
456  PushOnBack (new ClassProb (MLClass::CreateNewMLClass (className), probability, votes));
457  }
458 
459  delete t;
460  t = NULL;
461 } /* ReadXML */
462 
463 
464 
465 XmlFactoryMacro(ClassProbList)
XmlTag(const KKStr &_name, TagTypes _tagType)
Definition: XmlStream.cpp:586
void ReadXML(XmlStream &s, XmlTagConstPtr tag, VolConstBool &cancelFlag, RunLog &log)
Definition: ClassProb.cpp:423
ClassProbList * ClassProbListPtr
Definition: ClassProb.h:47
__int32 kkint32
Definition: KKBaseTypes.h:88
void TrimWhiteSpace(const char *_whiteSpace=" ")
After this call all leading and trailing whitespace will be trimmed from tokens.
Definition: KKStrParser.cpp:95
KKStr ExtractToken2(const char *delStr="\n\t\r ")
Extract first Token from the string.
Definition: KKStr.cpp:3026
kkint32 MemoryConsumedEstimated() const
Definition: ClassProb.cpp:68
KKStr GetNextToken(const char *delStr="\n\t\r ")
Extract next Token from string, tokens will be separated by delimiter characters. ...
void MergeIn(const ClassProbPtr cp)
Adds the Prediction in &#39;cp&#39; into this list.
Definition: ClassProb.cpp:268
virtual void PushOnBack(ClassProbPtr cp)
Definition: ClassProb.cpp:212
Represents a "Class" in the Machine Learning Sense.
Definition: MLClass.h:52
XmlContent * XmlContentPtr
Definition: XmlStream.h:24
kkint32 LookUpPlace(MLClassPtr targetClass) const
Returns the position that &#39;targetClass&#39; has in the order; good time to use would be after sorting by ...
Definition: ClassProb.cpp:174
KKStr operator+(const char *right) const
Definition: KKStr.cpp:3986
XmlToken * XmlTokenPtr
Definition: XmlStream.h:18
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
bool operator()(const ClassProbPtr left, const ClassProbPtr right)
Definition: ClassProb.cpp:116
float GetNextTokenFloat(const char *delStr="\n\t\r ")
KKStr & operator=(KKStr &&src)
Definition: KKStr.cpp:1369
void WriteXML(const KKStr &varName, std::ostream &o) const
Definition: ClassProb.cpp:400
KKTHread * KKTHreadPtr
KKStrParser(const KKStr &_str)
Definition: KKStrParser.cpp:42
virtual void PushOnFront(ClassProbPtr cp)
Definition: ClassProb.cpp:229
KKStr operator+(const char *left, const KKStr &right)
Definition: KKStr.cpp:3976
const ClassProbPtr LookUp(MLClassPtr targetClass) const
Definition: ClassProb.cpp:160
double ExtractTokenDouble(const char *delStr)
Definition: KKStr.cpp:3180
void SortByProbability(bool highToLow=true)
Definition: ClassProb.cpp:143
void AddAtribute(const KKStr &attributeName, const KKStr &attributeValue)
Definition: XmlStream.cpp:602
Used to record probability for a specified class; and a list of classes.
Definition: ClassProb.h:25
bool Empty() const
Definition: KKStr.h:241
XmlTag const * XmlTagConstPtr
Definition: KKStr.h:45
Manages the reading and writing of objects in a simple XML format. For a class to be supported by Xml...
Definition: XmlStream.h:46
void MergeIn(MLClassPtr target, double probability, float votes)
Adds the prediction of &#39;target&#39; with &#39;probability&#39; into this list.
Definition: ClassProb.cpp:276
virtual void DeleteEntry(kkuint32 idx)
Definition: ClassProb.cpp:198
ClassProbList(bool owner)
Definition: ClassProb.cpp:48
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of &#39;std::string&#39; strings.
Definition: KKStr.cpp:1082
double probability
Definition: ClassProb.h:36
KKB::KKStr osReadRestOfLine2(std::istream &in, bool &eof)
ClassProbList(const ClassProbList &pairList)
Definition: ClassProb.cpp:55
void AddIn(const ClassProbListPtr otherPredictions)
Adds the contents of &#39;otherPredictions&#39; to this list.
Definition: ClassProb.cpp:246
bool StartsWith(const char *value) const
Definition: KKStr.cpp:1144
double GetNextTokenDouble(const char *delStr="\n\t\r ")
void SortByVotes(bool highToLow=true)
Definition: ClassProb.cpp:151
const KKStr & UpperName() const
Definition: MLClass.h:155
virtual void DeleteEntry(ClassProbPtr cp)
Definition: ClassProb.cpp:187
const KKStr & Name() const
Definition: MLClass.h:154
void MergeIn(MLClassPtr target, const ClassProbListPtr subPredictions)
Merges in the predictions in &#39;subPredictions&#39; by replacing the entry in our list with label &#39;target&#39; ...
Definition: ClassProb.cpp:301
ClassProb(const ClassProb &_pair)
Definition: ClassProb.cpp:33
static MLClassPtr CreateNewMLClass(const KKStr &_name, kkint32 _classId=-1)
Static method used to create a new instance of a MLClass object.
Definition: MLClass.cpp:100
static ClassProbListPtr CreateFromXMLStream(std::istream &i)
Definition: ClassProb.cpp:362
void NormalizeToOne()
Will normalize the list of predictions such that the total probability will equal 1...
Definition: ClassProb.cpp:336
void WriteXML(std::ostream &o)
Definition: XmlStream.cpp:723
bool operator()(const ClassProbPtr left, const ClassProbPtr right)
Definition: ClassProb.cpp:95
KKStrPtr const Content() const
Definition: XmlStream.h:338
Used for logging messages.
Definition: RunLog.h:49
void EncodeProblem(const struct svm_paramater &param, struct svm_problem &prob_in, struct svm_problem &prob_out)
bool operator<(const KKStr &right) const
Definition: KKStr.cpp:1635
Class that manages the extraction of tokens from a String without being destructive to the original s...
Definition: KKStrParser.h:18
virtual XmlTokenPtr GetNextToken(VolConstBool &cancelFlag, RunLog &log)
Definition: XmlStream.cpp:116
KKException(const KKStr &_exceptionStr)
Definition: KKException.cpp:45
ClassProb(MLClassPtr _classLabel, double _probability, float _votes)
Definition: ClassProb.cpp:22
MLClassPtr classLabel
Definition: ClassProb.h:35
#define XmlFactoryMacro(NameOfClass)
Definition: XmlStream.h:688
volatile const bool VolConstBool
Definition: KKBaseTypes.h:163