Machine learning algorithms in C++
ClassifierUtils.hpp
Go to the documentation of this file.
1 
7 #ifndef MACHINE_LEARNING_CLASSIFIERUTILS_HPP
8 #define MACHINE_LEARNING_CLASSIFIERUTILS_HPP
9 
11  private:
12  static size_t findLabel(MatrixD y, double label) {
13  for (size_t i = 0; i < y.nRows(); i++)
14  if (label == y(i, 0))
15  return i;
16 
17  return 0;
18  }
19 
20  static MatrixD getAllClasses(const MatrixD yTrue, const MatrixD yPred) {
21  MatrixD allClasses = yTrue;
22  allClasses.addColumn(yPred);
23  allClasses = allClasses.unique();
24  allClasses.sort();
25  return allClasses;
26  }
27 
28  public:
29  static void checkLabels(const MatrixD yTrue, const MatrixD yPred) {
30  if (yTrue.nCols() != 1 or yPred.nCols() != 1)
31  throw invalid_argument("Labels must be column vectors");
32  if (yTrue.nRows() != yPred.nRows())
33  throw invalid_argument("True labels and predicted labels must have the same size (number of rows).");
34  }
35 
36  static void checkBinaryLabels(const MatrixD yTrue, const MatrixD yPred) {
37  checkLabels(yTrue, yPred);
38  if (!yTrue.isBinary())
39  throw invalid_argument("True labels must be composed of only two classes");
40  if (!yPred.isBinary())
41  throw invalid_argument("Predicted labels must be composed of only two classes");
42  }
43 
44  static MatrixI binarize(MatrixD m, double trueLabel) {
45  return m == trueLabel;
46  }
47 
48  static MatrixI confusionMatrix(MatrixD yTrue, MatrixD yPred) {
49  checkLabels(yTrue, yPred);
50 
51  MatrixD allClasses = getAllClasses(yTrue, yPred);
52 
53  MatrixI result = MatrixI::zeros(allClasses.nRows(), allClasses.nRows());
54 
55  for (size_t i = 0; i < yTrue.nRows(); i++) {
56  size_t tLabel = findLabel(allClasses, yTrue(i, 0));
57  size_t pLabel = findLabel(allClasses, yPred(i, 0));
58 
59  result(pLabel, tLabel) += 1;
60  }
61 
62  return result;
63  }
64 
65  static double accuracy(MatrixD yTrue, MatrixD yPred) {
66  checkLabels(yTrue, yPred);
67  double accuracy = 0;
68  for (size_t i = 0; i < yTrue.nRows(); i++)
69  accuracy += yTrue(i, 0) == yPred(i, 0);
70 
71  return accuracy / yTrue.nRows();
72  }
73 
74  static double precision(MatrixD yTrue, MatrixD yPred) {
75  checkBinaryLabels(yTrue, yPred);
76  MatrixI cm = confusionMatrix(yTrue, yPred);
77  return cm(1, 1) / ((double) cm(1, 1) + cm(1, 0));
78  }
79 
80  static double recall(MatrixD yTrue, MatrixD yPred) {
81  checkBinaryLabels(yTrue, yPred);
82  MatrixI cm = confusionMatrix(yTrue, yPred);
83  return cm(1, 1) / ((double) cm(1, 1) + cm(0, 1));
84  }
85 
86  static double f_score(MatrixD yTrue, MatrixD yPred) {
87  checkBinaryLabels(yTrue, yPred);
88  double p = precision(yTrue, yPred), r = recall(yTrue, yPred);
89  return 2 * ((p * r) / (p + r));
90  }
91 };
92 
93 #endif //MACHINE_LEARNING_CLASSIFIERUTILS_HPP
static MatrixI binarize(MatrixD m, double trueLabel)
static double recall(MatrixD yTrue, MatrixD yPred)
static void checkBinaryLabels(const MatrixD yTrue, const MatrixD yPred)
static double f_score(MatrixD yTrue, MatrixD yPred)
static MatrixD getAllClasses(const MatrixD yTrue, const MatrixD yPred)
static MatrixI confusionMatrix(MatrixD yTrue, MatrixD yPred)
static void checkLabels(const MatrixD yTrue, const MatrixD yPred)
static double precision(MatrixD yTrue, MatrixD yPred)
static size_t findLabel(MatrixD y, double label)
static double accuracy(MatrixD yTrue, MatrixD yPred)