KSquare Utilities
ClassificationBiasMatrix.cpp
Go to the documentation of this file.
1 #include "FirstIncludes.h"
2 
3 #include <stdio.h>
4 #include <math.h>
5 #include <ctype.h>
6 #include <time.h>
7 #include <fstream>
8 #include <iostream>
9 #include <map>
10 #include <ostream>
11 #include <string>
12 #include <vector>
13 using namespace std;
14 
15 #include "MemoryDebug.h"
16 
17 
18 #include "KKBaseTypes.h"
19 #include "KKException.h"
20 #include "KKStr.h"
21 #include "Matrix.h"
22 #include "OSservices.h"
23 #include "RunLog.h"
24 using namespace KKB;
25 
26 
27 #include "MLClass.h"
28 using namespace KKMLL;
29 
31 
32 
33 
34 ClassificationBiasMatrix::ClassificationBiasMatrix (const KKStr& _configFileName,
35  MLClassList& _classes,
36  RunLog& _runLog
37  ):
38  biasFileName (),
39  classes (new MLClassList (_classes)),
40  configFileName (_configFileName),
41  configFileNameFromMatrixBiasFile (),
42  configDateTime (),
43  counts (NULL),
44  dateTimeFileWritten (),
45  errMsgs (),
46  numClasses (0),
47  probabilities (NULL),
48  runLog (_runLog),
49  valid (true)
50 {
51  biasFileName = osRemoveExtension (configFileName) + ".BiasMatrix.txt";
52 
53  ifstream sr (biasFileName.Str ());
54 
55  if (!sr.is_open ())
56  {
57  valid = false;
58  KKStr errorMsg = "Error opening ConfigFileName[" + configFileName + "]";
59  errMsgs.push_back (errorMsg);
60  return;
61  }
62 
63  DeclareMatrix ();
64 
65  try
66  {
67  ReadXML (sr);
68  }
69  catch (const exception& e)
70  {
71  valid = false;
72  errMsgs.push_back (e.what ());
73  }
74  catch (...)
75  {
76  valid = false;
77  errMsgs.push_back ("ClassificationBiasMatrix Exception occurred reading XML File");
78  }
79  sr.close ();
80 }
81 
82 
83 
85  biasFileName (cbm.biasFileName),
86  classes (NULL),
87  configFileName (cbm.configFileName),
88  configFileNameFromMatrixBiasFile (cbm.configFileNameFromMatrixBiasFile),
89  configDateTime (cbm.configDateTime),
90  counts (NULL),
91  dateTimeFileWritten (cbm.dateTimeFileWritten),
92  errMsgs (),
93  numClasses (cbm.numClasses),
94  probabilities (NULL),
95  runLog (cbm.runLog),
96  valid (true)
97 
98 {
99  if (cbm.counts)
100  counts = new Matrix (*cbm.counts);
101 
102  if (cbm.classes)
103  classes = new MLClassList (*cbm.classes);
104 
105  if (cbm.probabilities)
106  probabilities = new Matrix (*cbm.probabilities);
107 }
108 
109 
110 
111 
113  RunLog& _runLog
114  ):
115  biasFileName (),
116  classes (NULL),
117  configFileName (),
118  configFileNameFromMatrixBiasFile (),
119  configDateTime (),
120  counts (NULL),
121  dateTimeFileWritten (),
122  errMsgs (),
123  numClasses (0),
124  probabilities (NULL),
125  runLog (_runLog),
126  valid (true)
127 {
128  classes = new MLClassList (cm.MLClasses ());
129  numClasses = classes->QueueSize ();
130  DeclareMatrix ();
131  BuildFromConfusionMatrix (cm);
132 }
133 
134 
135 
137  RunLog& _runLog
138  ):
139  biasFileName (),
140  classes (new MLClassList (_classes)),
141  configFileName (),
142  configFileNameFromMatrixBiasFile (),
143  configDateTime (),
144  counts (NULL),
145  dateTimeFileWritten (),
146  errMsgs (),
147  numClasses (0),
148  probabilities (NULL),
149  runLog (_runLog),
150  valid (true)
151 
152 {
153  numClasses = classes->QueueSize ();
154  DeclareMatrix ();
155 }
156 
157 
158 
160  biasFileName (),
161  classes (new MLClassList ()),
162  configFileName (),
163  configFileNameFromMatrixBiasFile (),
164  configDateTime (),
165  counts (NULL),
166  dateTimeFileWritten (),
167  errMsgs (),
168  numClasses (0),
169  probabilities (NULL),
170  runLog (_runLog),
171  valid (true)
172 {
173  BuildTestMatrix ();
174 
175  //ofstream sw ("c:\\Temp\\ClassificationBiasMatrix_Test.txt");
176  //TestPaperResults (sw);
177  //sw.close ();
178 }
179 
180 
181 
182 
184 {
185  delete probabilities;
186  probabilities = NULL;
187  delete counts;
188  counts = NULL;
189  delete classes;
190  classes = NULL;
191 }
192 
193 
194 
195 ClassificationBiasMatrixPtr ClassificationBiasMatrix::BuildFromIstreamXML (istream& f,
196  MLClassList& classes,
197  RunLog& log
198  )
199 {
201  cbm->ReadXML (f);
202  return cbm;
203 } /* BuildFromIstreamXML */
204 
205 
206 
207 
208 
209 void ClassificationBiasMatrix::DeclareMatrix ()
210 {
211  numClasses = classes->QueueSize ();
212  probabilities = new Matrix (numClasses, numClasses);
213  counts = new Matrix (numClasses, numClasses);
214  for (kkint32 r = 0; r < numClasses; r++)
215  {
216  for (kkint32 c = 0; c < numClasses; c++)
217  {
218  (*probabilities)[r][c] = 0.0;
219  (*counts)[r][c] = 0.0;
220  }
221  }
222 } /* DeclareMatrix */
223 
224 
225 
226 
227 void ClassificationBiasMatrix::BuildTestMatrix ()
228 {
229  classes = new MLClassList ();
230 
238 
239  numClasses = classes->QueueSize ();
240 
241  probabilities = new Matrix (numClasses, numClasses);
242  counts = new Matrix (numClasses, numClasses);
243 
244  Row& r0 = (*probabilities)[0];
245  Row& r1 = (*probabilities)[1];
246  Row& r2 = (*probabilities)[2];
247  Row& r3 = (*probabilities)[3];
248  Row& r4 = (*probabilities)[4];
249  Row& r5 = (*probabilities)[5];
250  Row& r6 = (*probabilities)[6];
251 
252  r0[0] = 0.710; r0[1] = 0.059; r0[2] = 0.010; r0[3] = 0.010; r0[4] = 0.007; r0[5] = 0.031; r0[6] = 0.175;
253  r1[0] = 0.073; r1[1] = 0.873; r1[2] = 0.001; r1[3] = 0.007; r1[4] = 0.008; r1[5] = 0.013; r1[6] = 0.024;
254  r2[0] = 0.078; r2[1] = 0.012; r2[2] = 0.556; r2[3] = 0.035; r2[4] = 0.066; r2[5] = 0.179; r2[6] = 0.074;
255  r3[0] = 0.030; r3[1] = 0.028; r3[2] = 0.054; r3[3] = 0.560; r3[4] = 0.019; r3[5] = 0.177; r3[6] = 0.132;
256  r4[0] = 0.205; r4[1] = 0.054; r4[2] = 0.107; r4[3] = 0.046; r4[4] = 0.366; r4[5] = 0.157; r4[6] = 0.065;
257  r5[0] = 0.158; r5[1] = 0.025; r5[2] = 0.076; r5[3] = 0.064; r5[4] = 0.175; r5[5] = 0.449; r5[6] = 0.054;
258  r6[0] = 0.289; r6[1] = 0.096; r6[2] = 0.033; r6[3] = 0.065; r6[4] = 0.018; r6[5] = 0.072; r6[6] = 0.427;
259 } /* BuildTestMatrix */
260 
261 
262 
263 
265 {
266  VectorDouble classCounts (7, 0.0);
267  classCounts[0] = 2891;
268  classCounts[1] = 1965;
269  classCounts[2] = 495;
270  classCounts[3] = 1399;
271  classCounts[4] = 676;
272  classCounts[5] = 1191;
273  classCounts[6] = 1752;
274 
275  VectorDouble adjCounts;
276  VectorDouble stdErrors;
277 
278  PerformAdjustmnts (classCounts, adjCounts, stdErrors);
279 
280  kkint32 x = 0;
281 
282  sw << endl << endl;
283 
285 
286  sw << endl << endl;
287 
288  sw << "Desc";
289  for (x = 0; x < 7; x++)
290  sw << "\t" << StrFormatInt (x, "ZZ0");
291  sw << endl;
292 
293  sw << "ClassifiedCounts";
294  for (x = 0; x < 7; x++)
295  sw << "\t" << StrFormatDouble (classCounts[x], "ZZ,ZZ0.0");
296  sw << endl;
297 
298  sw << "adjCounts";
299  for (x = 0; x < 7; x++)
300  sw << "\t" << StrFormatDouble (adjCounts[x], "ZZZ,ZZ0.0");
301  sw << endl;
302 
303  sw << "stdErrors";
304  for (x = 0; x < 7; x++)
305  sw << "\t" << StrFormatDouble (stdErrors[x], "ZZ,ZZ0.0");
306 
307  sw << endl << endl;
308 } /* TestPaperResults*/
309 
310 
311 
312 
313 void ClassificationBiasMatrix::ReadXML (istream& sr)
314 {
315  char buff[10240];
316  KKStr l (512);
317 
318  if (sr.eof ())
319  return;
320 
321  MLClassListPtr fileClasses = NULL;
322 
323  sr.getline (buff, sizeof (buff));
324  while (!sr.eof ())
325  {
326  l = buff;
327  l.TrimRight ();
328  if (l.CompareIgnoreCase ("</ClassificationBiasMatrix>") == 0)
329  break;
330 
331  KKStr lineName = l.ExtractToken2 ("\t");
332  if (!lineName.Empty ())
333  {
334  KKStr fieldValue = l.ExtractToken2 ("\t");
335 
336  if (lineName.CompareIgnoreCase ("Classes") == 0)
337  {
338  delete fileClasses; fileClasses = NULL;
339  fileClasses = MLClassList::BuildListFromDelimtedStr (fieldValue, ',');
340  if (classes == NULL)
341  classes = new MLClassList (*fileClasses);
342  }
343 
344  else if (lineName.CompareIgnoreCase ("ConfigDateTime") == 0)
345  {
346  configDateTime = fieldValue;
347  }
348 
349  else if (lineName.CompareIgnoreCase ("ConfigFileName") == 0)
350  {
351  configFileNameFromMatrixBiasFile = fieldValue;
352  }
353 
354  else if (lineName.CompareIgnoreCase ("ConfigFileDateTime") == 0)
355  {
356  configDateTime = fieldValue;
357  }
358 
359  else if (lineName.CompareIgnoreCase ("DateTime") == 0)
360  {
361  dateTimeFileWritten = fieldValue;
362  }
363 
364  else if (lineName.CompareIgnoreCase ("DateTimeFileWritten") == 0)
365  {
366  dateTimeFileWritten = fieldValue;
367  }
368 
369  else if (lineName.CompareIgnoreCase ("FileName") == 0)
370  {
371  }
372 
373  else if (lineName.CompareIgnoreCase ("NumClasses") == 0)
374  {
375  numClasses = fieldValue.ToInt ();
376  }
377 
378  else if (lineName.CompareIgnoreCase ("<SimpleConfusionMatrix>") == 0)
379  {
380  ReadSimpleConfusionMatrix (sr, fileClasses);
381  }
382  }
383 
384  if (!sr.eof ())
385  sr.getline (buff, sizeof (buff));
386  }
387 } /* ReadXML */
388 
389 
390 
391 
392 void ClassificationBiasMatrix::ReadSimpleConfusionMatrix (istream& sr,
393  MLClassListPtr fileClasses
394  )
395 {
396  // 'classes' - The class order that the owner of this object is expecting.
397  // 'fileClasses' - The order that the classes are stored in the text file.
398 
399 
400  if ((classes == NULL) || (fileClasses == NULL))
401  {
402  KKStr errMsg = "ReadSimpleConfusionMatrix ***ERROR*** The 'Classes' line was never provided.";
403  runLog.Level (-1) << errMsg << endl;
404  valid = false;
405  throw KKException (errMsg);
406  }
407 
408  kkint32 classesColIdx = 0;
409 
410  char buff[10240];
411  KKStr l;
412  while (!sr.eof ())
413  {
414  sr.getline (buff, sizeof (buff));
415  l = buff;
416  l.TrimLeft ();
417  l.TrimRight ();
418 
419  if (l.CompareIgnoreCase ("</SimpleConfusionMatrix>") == 0)
420  break;
421 
422  KKStr lineName = l.ExtractToken2 ("\t");
423 
424  if (lineName.CompareIgnoreCase ("DataRow") == 0)
425  {
426  if (fileClasses == NULL)
427  {
428  KKStr errMsg = "ReadSimpleConfusionMatrix ***ERROR*** 'Classes' was not provided before 'DataRow'.";
429  runLog.Level (-1) << errMsg << endl;
430  valid = false;
431  throw KKException (errMsg);
432  }
433 
434  KKStr className = l.ExtractToken2 ("\t");
435  KKStr data = l.ExtractToken2 ("\t");
436 
437  MLClassPtr pc = MLClass::CreateNewMLClass (className);
438  kkint32 classesIdx = classes->PtrToIdx (pc);
439  kkint32 fileClassesIdx = fileClasses->PtrToIdx (pc);
440 
441  if (classesIdx < 0)
442  {
443  KKStr errMsg = "ReadSimpleConfusionMatrix ***ERROR*** DataRow specifies class[" + className + "] which is not defined by caller";
444  runLog.Level (-1) << errMsg << endl;
445  valid = false;
446  throw KKException (errMsg);
447  }
448 
449  if (fileClassesIdx < 0)
450  {
451  KKStr errMsg = "ReadSimpleConfusionMatrix ***ERROR*** DataRow specifies class[" + className + "] was not defined in 'Classes' line.";
452  runLog.Level (-1) << errMsg << endl;
453  valid = false;
454  throw KKException (errMsg);
455  }
456 
457  kkint32 classesRowIdx = classesIdx;
458 
459  VectorKKStr dataFields = data.Split (',');
460  if (dataFields.size () != (kkuint32)numClasses)
461  {
462  KKStr errMsg = "ReadSimpleConfusionMatrix ***ERROR*** DataRow Class[" + className + "] number[" + StrFormatInt ((kkint32)dataFields.size (), "ZZZ0") + "] of values provided does not match number of Classes.";
463  runLog.Level (-1) << errMsg << endl;
464  valid = false;
465  throw KKException (errMsg);
466  }
467 
468  for (kkint32 c = 0; c < numClasses; c++)
469  {
470  pc = fileClasses->IdxToPtr (c);
471  classesColIdx = classes->PtrToIdx (pc);
472 
473  VectorKKStr parts = dataFields[c].Split (':');
474  if (parts.size () > 1)
475  {
476  (*counts) [classesRowIdx][classesColIdx] = parts[0].ToDouble ();
477  (*probabilities)[classesRowIdx][classesColIdx] = parts[1].ToDouble ();
478  }
479  }
480  }
481  }
482 } /* ReadSimpleConfusionMatrix */
483 
484 
485 
486 
487 void ClassificationBiasMatrix::WriteXML (std::ostream& o)
488 {
489  o << "<ClassificationBiasMatrix>" << std::endl;
490 
491  o << "BiasFileName" << "\t" << biasFileName << std::endl;
492 
493  if ((!classes) || (!counts) || (!probabilities))
494  {
495  runLog.Level (-1) << "ClassificationBiasMatrix::WriteXML ***ERROR*** Not all data is defined." << endl;
496  return;
497  }
498 
499  if ((numClasses != classes->QueueSize ()) ||
500  (numClasses != counts->NumOfRows ()) ||
501  (numClasses != probabilities->NumOfRows ())
502  )
503  {
504  runLog.Level (-1) << "ClassificationBiasMatrix::WriteXML ***ERROR*** Disagreement in variable dimensions." << endl;
505  return;
506  }
507 
508  o << "NumClasses" << "\t" << numClasses << std::endl;
509  o << "Classes" << "\t" << classes->ToCommaDelimitedStr () << std::endl;
510  o << "ConfigFileName" << "\t" << configFileName << std::endl;
511  o << "ConfigDateTime" << "\t" << configDateTime << std::endl;
512  o << "DateTimeFileWritten" << "\t" << dateTimeFileWritten << std::endl;
513 
514  o << "<SimpleConfusionMatrix>" << std::endl;
515  for (kkint32 rowIdx = 0; rowIdx < numClasses; rowIdx++)
516  {
517  o << "DataRow" << "\t"
518  << (*classes)[rowIdx].Name () << "\t";
519 
520  for (kkint32 colIdx = 0; colIdx < numClasses; colIdx++)
521  {
522  if (colIdx > 0)
523  o << ",";
524  o << ((*counts)[rowIdx][colIdx]) << ":" << StrFormatDouble ((*probabilities)[rowIdx][colIdx], "ZZ0.0000");
525  }
526  o << std::endl;
527  }
528 
529  o << "</SimpleConfusionMatrix>" << std::endl;
530 
531  o << "</ClassificationBiasMatrix>" << std::endl;
532 
533 } /* WriteXML */
534 
535 
536 
537 
538 
539 
540 void ClassificationBiasMatrix::BuildFromConfusionMatrix (const ConfusionMatrix2& cm)
541 {
542  kkint32 classesRowIdx = 0;
543  kkint32 classesColIdx = 0;
544 
545  for (classesRowIdx = 0; classesRowIdx < numClasses; classesRowIdx++)
546  {
547  double knownCount = cm.CountsByKnownClass (classesRowIdx);
548 
549  for (classesColIdx = 0; classesColIdx < numClasses; classesColIdx++)
550  {
551  double predCount = cm.PredictedCountsCM (classesRowIdx, classesColIdx);
552  double prob = 0.0;
553  if (knownCount != 0.0)
554  prob = predCount / knownCount;
555 
556  (*counts) [classesRowIdx][classesColIdx] = predCount;
557  (*probabilities)[classesRowIdx][classesColIdx] = prob;
558  }
559  }
560 } /* BuildFromConfusionMatrix*/
561 
562 
563 
564 
566  VectorDouble& adjCounts,
567  VectorDouble& stdErrors
568  )
569 {
570  // For description of calc's see the paper:
571  // "Estimating the Taxonomic composition of a sample when individuals are classified with error"
572  // by Andrew Solow, Cabll Davis, Qiao Hu
573  // Woods Hole Oceanographic Institution, Woods Hole Massachusetts
574  // Marine Ecology Progress Series
575  // published 2006-july-06; vol 216:309-311
576 
577  if (classifiedCounts.size () != (kkuint32)numClasses)
578  {
579  KKStr errMsg = "ClassificationBiasMatrix::PerformAdjustmnts ***ERROR*** Disagreement in length of classifiedCounts[" +
580  StrFormatInt ((kkint32)classifiedCounts.size (), "ZZZ0") +
581  "] and Prev Defined ClassList[" + StrFormatInt (numClasses, "ZZZ0") + "].";
582  runLog.Level (-1) << errMsg << endl;
583  valid = false;
584  throw KKException (errMsg);
585  }
586 
587  kkint32 x = 0;
588  kkint32 i, j, k;
589 
590 
591  // We need to deal with the special case when one entry in the probability diagonal is zero.
592  {
593  for (x = 0; x < numClasses; x++)
594  {
595  if ((*probabilities)[x][x] == 0.0)
596  {
597  // This will cause the inversion of the diagonal matrix to fail. To deal
598  // with this situation; I will steal some probability from other buckets on
599  // same row.
600 
601  double totalAmtStolen = 0.0;
602  double percentToSteal = 0.01;
603  for (i = 0; i < numClasses; i++)
604  {
605  if ((*probabilities)[x][i] != 0.0)
606  {
607  double amtToSteal = (*probabilities)[x][i] * percentToSteal;
608  (*probabilities)[x][i] = (*probabilities)[x][i] - amtToSteal;
609  totalAmtStolen += amtToSteal;
610  }
611  }
612 
613  (*probabilities)[x][x] = totalAmtStolen;
614  }
615  }
616  }
617 
618  Matrix m (numClasses, 1);
619  for (x = 0; x < numClasses; x++)
620  m[x][0] = classifiedCounts[x];
621 
622  Matrix transposed = probabilities->Transpose ();
623  Matrix Q = transposed.Inverse ();
624  Matrix n = Q * m;
625 
626  Matrix varM (numClasses, numClasses);
627  for (j = 0; j < numClasses; j++)
628  {
629  double varM_j = 0.0;
630  for (i = 0; i < numClasses; i++)
631  {
632  double p = (*probabilities)[i][j];
633  varM_j += n[i][0] * p * (1.0 - p);
634  }
635  varM[j][j] = varM_j;
636  }
637 
638  for (j = 0; j < numClasses; j++)
639  {
640  for (k = 0; k < numClasses; k++)
641  {
642  if (j != k)
643  {
644  double covM_jk = 0.0;
645  for (i = 0; i < numClasses; i++)
646  covM_jk -= n[i][0] * (*probabilities)[i][j] * (*probabilities)[j][k];
647  varM[j][k] = covM_jk;
648  }
649  }
650  }
651 
652  Matrix varN = Q * varM * Q.Transpose ();
653 
654  adjCounts.clear ();
655  stdErrors.clear ();
656 
657  for (x = 0; x < numClasses; x++)
658  {
659  adjCounts.push_back (n[x][0]);
660  stdErrors.push_back (sqrt (varN[x][x]));
661  }
662 
663  return;
664 } /* PerformAdjustmnts */
665 
666 
667 
669 {
670  if (classes == NULL)
671  {
672  KKStr errMsg = "ClassificationBiasMatrix::PrintBiasMatrix ***ERROR*** 'Classes' not defined; this indicates that this object was not properly initialized.";
673  runLog.Level (-1) << errMsg << endl;
674  valid = false;
675  throw KKException (errMsg);
676  }
677 
678  sw << "BiasMatrix File Name [" << biasFileName << "]" << endl
679  << "Date Bias Matrix was Created [" << dateTimeFileWritten << "]" << endl
680  << "Configuration File Name [" << configFileName << "]" << endl
681  << "ConfigFile Used for Bias Matrix [" << configFileNameFromMatrixBiasFile << "]" << endl
682  << endl
683  << endl;
684 
685  KKStr tl1, tl2, tl3;
686 
687  classes->ExtractThreeTitleLines (tl1, tl2, tl3);
688  {
689  sw << "" << "\t" << "" << "\t" << tl1 << endl;
690  sw << "Class" << "\t" << "" << "\t" << tl2 << endl;
691  sw << "Name" << "\t" << "Count" << "\t" << tl3 << endl;
692  }
693 
694  kkint32 row = 0;
695  kkint32 col = 0;
696 
697  double total = 0.0;
698 
699  VectorDouble colTotals (numClasses, 0.0);
700  VectorDouble rowTotals (numClasses, 0.0);
701 
702  for (row = 0; row < numClasses; row++)
703  {
704  double rowTotal = 0;
705  for (col = 0; col < numClasses; col++)
706  {
707  rowTotal += (*counts)[row][col];
708  colTotals[col] += (*counts)[row][col];
709  }
710  rowTotals[row] = rowTotal;
711 
712  sw << (*classes)[row].Name () << "\t" << StrFormatDouble (rowTotal, "zzz,zz0.00");
713  for (col = 0; col < numClasses; col++)
714  sw << "\t" << StrFormatDouble ((*counts)[row][col], "###,##0.00");
715  sw << endl;
716  total += rowTotal;
717  }
718  sw << "Total" << "\t" << StrFormatDouble (total, "###,##0.00");
719  for (col = 0; col < numClasses; col++)
720  sw << "\t" << StrFormatDouble (colTotals[col], "ZZZ,ZZ0.00");
721  sw << endl;
722 
723  sw << endl;
724 
725  for (row = 0; row < numClasses; row++)
726  {
727  sw << (*classes)[row].Name ();
728  double rowPercent = 100.0 * rowTotals[row] / total;
729  sw << "\t" << StrFormatDouble (rowPercent, "ZZ0.0000") + "%";
730 
731  for (col = 0; col < numClasses; col++)
732  sw << "\t" << StrFormatDouble (100.0 * (*probabilities)[row][col], "ZZZ,ZZ0.00") << "%";
733  sw << endl;
734  }
735  sw << endl;
736 } /* PrintBiasMatrix */
737 
738 
739 
740 
742  const VectorDouble& classifiedCounts
743  )
744 {
745  if (classifiedCounts.size () != (kkuint32)numClasses)
746  {
747  KKStr errMsg = "ClassificationBiasMatrix::PrintAdjustedResults ***ERROR*** Number of entries in 'classifiedCounts' not equal the number of classes";
748  cerr << "ClassificationBiasMatrix::PrintAdjustedResults ***ERROR*** " << errMsg << endl;
749  valid = false;
750  throw KKException (errMsg);
751  }
752 
753  try
754  {
755  VectorDouble adjustedReults;
756  VectorDouble stdErrors;
757 
758  PerformAdjustmnts (classifiedCounts, adjustedReults, stdErrors);
759 
760  KKStr tl1, tl2, tl3;
761  classes->ExtractThreeTitleLines (tl1, tl2, tl3);
762  sw << "" << "\t" << "\t" << tl1 << endl;
763  sw << "" << "\t" << "\t" << tl2 << endl;
764  sw << "Description" << "\t" << "\t" << tl3 << endl;
765 
766  kkint32 col = 0;
767 
768  sw << "Classified Results" << "\t";
769  for (col = 0; col < numClasses; col++)
770  sw << "\t" << StrFormatDouble (classifiedCounts[col], "Z,ZZZ,ZZ0.0");
771  sw << endl;
772 
773  sw << "Adjusted Results" << "\t";
774  for (col = 0; col < numClasses; col++)
775  sw << "\t" << StrFormatDouble (adjustedReults[col], "Z,ZZZ,ZZ0.0");
776  sw << endl;
777 
778  sw << "Standard Errors" << "\t";
779  for (col = 0; col < numClasses; col++)
780  sw << "\t" << StrFormatDouble (stdErrors[col], "Z,ZZZ,ZZ0.0");
781  sw << endl;
782  }
783  catch (KKException& e)
784  {
785  KKStr errMsg = "ClassificationBiasMatrix::PrintAdjustedResults ***ERROR*** KKException";
786  runLog.Level (-1) << errMsg << endl << e.ToString () << endl;
787  throw KKException (errMsg, e);
788  }
789  catch (std::exception& e2)
790  {
791  KKStr errMsg = "ClassificationBiasMatrix::PrintAdjustedResults ***ERROR*** std::exception";
792  runLog.Level (-1) << errMsg << endl << e2.what() << endl;
793  throw KKException (errMsg, e2);
794  }
795  catch (...)
796  {
797  KKStr errMsg = "ClassificationBiasMatrix::PrintAdjustedResults ***ERROR*** Exception(...)";
798  runLog.Level (-1) << endl << errMsg << endl;
799  throw KKException (errMsg);
800  }
801 } /* PrintAdjustedResults */
Row & operator[](kkint32 rowIDX) const
Definition: Matrix.cpp:270
KKStr(kkint32 size)
Creates a KKStr object that pre-allocates space for &#39;size&#39; characters.
Definition: KKStr.cpp:655
Matrix Transpose()
Definition: Matrix.cpp:707
ClassificationBiasMatrix(const ClassificationBiasMatrix &cbm)
void PerformAdjustmnts(const VectorDouble &classifiedCounts, VectorDouble &adjCounts, VectorDouble &stdErrors)
KKStr osRemoveExtension(const KKStr &_fullFileName)
__int32 kkint32
Definition: KKBaseTypes.h:88
ClassificationBiasMatrix(const KKStr &_configFileName, MLClassList &_classes, RunLog &_runLog)
Construct a ClassificationBiasMatrix instance from the parameter file for &#39;_configFileName&#39;.
void PrintAdjustedResults(ostream &sw, const VectorDouble &classifiedCounts)
KKException(const KKStr &_exceptionStr, const KKException &_innerException)
Definition: KKException.cpp:83
ClassificationBiasMatrix(const ConfusionMatrix2 &cm, RunLog &_runLog)
Construct a ClassificationBiasMatrix instance from a ConfusionMatrix object.
ClassificationBiasMatrix(MLClassList &classes, RunLog &_runLog)
Matrix(kkint32 _numOfRows, kkint32 _numOfCols)
Definition: Matrix.cpp:108
Represents a "Class" in the Machine Learning Sense.
Definition: MLClass.h:52
Assists in adjusting a Classifiers output for bias of a classifier.
Matrix(const Matrix &_matrix)
Definition: Matrix.cpp:142
KKStr operator+(const char *right) const
Definition: KKStr.cpp:3986
KKException(const KKStr &_exceptionStr, const std::exception &_innerException)
Definition: KKException.cpp:52
double & operator[](kkint32 idx)
Definition: Matrix.cpp:76
Matrix operator*(const Matrix &right)
Definition: Matrix.cpp:478
KKStr & operator=(KKStr &&src)
Definition: KKStr.cpp:1369
double CountsByKnownClass(kkint32 knownClassIdx) const
static ClassificationBiasMatrixPtr BuildFromIstreamXML(istream &f, MLClassList &classes, RunLog &log)
Will construct a ClassificationBiasMatrix instance from a input stream.
KKTHread * KKTHreadPtr
KKStr(const KKStr &str)
Copy Constructor.
Definition: KKStr.cpp:561
virtual void PushOnBack(MLClassPtr mlClass)
Definition: MLClass.cpp:798
void ExtractThreeTitleLines(KKStr &titleLine1, KKStr &titleLine2, KKStr &titleLine3) const
Using the class names create three title lines where we split names by "_" characters between the thr...
Definition: MLClass.cpp:1068
DateTime(const DateTime &dateTime)
Definition: DateTime.cpp:1006
Matrix Inverse()
Definition: Matrix.cpp:731
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
MLClassList(const MLClassList &_mlClasses)
Copy constructor; will copy list but not own the contents.
Definition: MLClass.cpp:570
const MLClassList & MLClasses() const
void EncodeProblem(const struct svm_paramater &param, struct svm_problem &prob_in, struct svm_problem &prob_out)
MLClassList * MLClassListPtr
Definition: MLClass.h:49
KKException(const KKStr &_exceptionStr)
Definition: KKException.cpp:45
Maintains a list of MLClass instances.
Definition: MLClass.h:233
double PredictedCountsCM(kkint32 knownClassIdx, kkint32 predClassIdx) const
ClassificationBiasMatrix * ClassificationBiasMatrixPtr
A confusion matrix object that is used to record the results from a CrossValidation. <see also cref="CrossValidation"
std::vector< double > VectorDouble
Vector of doubles.
Definition: KKBaseTypes.h:148
ClassificationBiasMatrix(RunLog &_runLog)
Will construct an instance as defined in the Paper.