CVB++ 15.0
confusion_matrix.hpp
1#pragma once
2
3#include "../_cexports/c_polimago.h"
4
5#include "../global.hpp"
6#include "classification_test_result.hpp"
7
8#include <vector>
9
10namespace Cvb
11{
12 CVB_BEGIN_INLINE_NS
13
15 namespace Polimago
16 {
18 namespace Testing
19 {
20
22
24 class PredictionResult
25 {
26 public:
27 PredictionResult(const PredictionResult &other) = default;
28 PredictionResult &operator=(const PredictionResult &other) = default;
29 PredictionResult(PredictionResult &&other) = default;
30 PredictionResult &operator=(PredictionResult &&other) = default;
31 ~PredictionResult() = default;
32
33 private:
34 PredictionResult(const ClassificationTestResult &res, int exampleIndex)
35 : exampleIndex_(exampleIndex)
36 , confidence_(res.ExampleConfidences()[exampleIndex])
37 , confidenceDistribution_(res.ExampleConfidenceDistributions()[exampleIndex])
38 {
39 }
40 friend class ConfusionMatrix;
41
42 public:
45
49 int ExampleIndex() const noexcept
50 {
51 return exampleIndex_;
52 }
53
55
59 double Confidence() const noexcept
60 {
61 return confidence_;
62 }
63
65
70 {
71 return confidenceDistribution_;
72 }
73
74 private:
75 int exampleIndex_;
76 double confidence_;
77 std::vector<double> confidenceDistribution_;
78 };
79
81
87 {
88 public:
90
95 {
96 BuildConfusionMatrix(res);
97 UpdateVisibleMatrix();
98 }
99
100 public:
102
107 int TotalSamples(int classIndex) const
108 {
109 auto numClasses = NumClasses();
110 if (classIndex >= numClasses)
111 {
112 throw std::out_of_range("class index out of range");
113 }
114
115 int sum = 0;
116 for (decltype(numClasses) c = 0; c < numClasses; ++c)
117 {
118 sum += static_cast<int>(indexArray_[classIndex][c].size());
119 }
120 return sum;
121 }
122
124
128 int TotalSamples() const
129 {
130 auto numClasses = NumClasses();
131 int retval = 0;
132 for (decltype(numClasses) i = 0; i < numClasses; ++i)
133 {
134 retval += TotalSamples(i);
135 }
136 return retval;
137 }
138
140
145 int TotalCorrect(int classIndex) const
146 {
147 auto numClasses = NumClasses();
148 if (classIndex >= numClasses)
149 {
150 throw std::out_of_range("class index out of range");
151 }
152 return static_cast<int>(At(classIndex, classIndex).size());
153 }
154
156
160 int TotalCorrect() const
161 {
162 auto numClasses = NumClasses();
163 int sum = 0;
164 for (decltype(numClasses) i = 0; i < numClasses; ++i)
165 {
166 sum += TotalCorrect(i);
167 }
168 return sum;
169 }
170
172
177 int TotalErrors(int classIndex) const
178 {
179 auto numClasses = NumClasses();
180 if (classIndex >= numClasses)
181 {
182 throw std::out_of_range("class index out of range");
183 }
184
185 int sum = 0;
186 for (decltype(numClasses) c = 0; c < numClasses; ++c)
187 {
188 sum += static_cast<int>(indexArray_[classIndex][c].size());
189 if (c != classIndex)
190 {
191 sum += static_cast<int>(At(classIndex, c).size());
192 }
193 }
194 return sum;
195 }
196
198
202 int TotalErrors() const
203 {
204 auto numClasses = NumClasses();
205 int retval = 0;
206 for (decltype(numClasses) i = 0; i < numClasses; ++i)
207 {
208 retval += TotalErrors(i);
209 }
210 return retval;
211 }
212
215
219 int TotalRejects() const
220 {
221 int retval = 0;
222 for (auto &&r : rejects_)
223 {
224 retval += static_cast<int>(r.size());
225 }
226 return retval;
227 }
228
230
236 {
237 if (classIndex >= rejects_.size())
238 {
239 throw std::out_of_range("class index out of range");
240 }
241
242 return rejects_[classIndex];
243 }
244
246
250 int NumClasses() const noexcept
251 {
252 return static_cast<int>(indexArray_.size());
253 }
254
256
275 std::vector<PredictionResult> At(int trueClass, int predictedClass) const
276 {
277 if (trueClass >= NumClasses() || predictedClass >= NumClasses())
278 {
279 throw std::out_of_range("class index out of range");
280 }
281
282 return visibleArray_[trueClass][predictedClass];
283 }
284
286
290 double ConfidenceThreshold() const noexcept
291 {
292 return confidenceThreshold_;
293 }
294
296
303 void SetConfidenceThreshold(double threshold)
304 {
305 if ((threshold < 0.0) || (threshold > 1.5))
306 {
307 throw std::out_of_range("confidence threshold value must be within <0.0, 1.5>");
308 }
309 confidenceThreshold_ = threshold;
310 UpdateVisibleMatrix();
311 }
312
313 private:
314 void BuildConfusionMatrix(const ClassificationTestResult &res)
315 {
316 auto numClasses = res.NumClasses();
317 auto numExamples = res.NumExamples();
318 rejects_.resize(numClasses);
319
320 indexArray_.resize(numClasses);
321 for (auto &&indexRow : indexArray_)
322 {
323 indexRow.resize(numClasses);
324 }
325
326 for (decltype(numExamples) i = 0; i < numExamples; ++i)
327 {
328 auto trueIndex = res.TrueClassIndices()[i];
329 auto predictedIndex = res.PredictedClassIndices()[i];
330 indexArray_[trueIndex][predictedIndex].push_back(PredictionResult(res, i));
331 }
332 }
333
334 void UpdateVisibleMatrix()
335 {
336 for (auto &&r : rejects_)
337 {
338 r.clear();
339 }
340
341 if (ConfidenceThreshold() == 0.0)
342 {
343 visibleArray_ = indexArray_;
344 return;
345 }
346
347 visibleArray_.resize(indexArray_.size());
348 for (auto &&visibleRow : visibleArray_)
349 {
350 visibleRow.resize(indexArray_[0].size());
351 }
352 for (size_t x = 0; x < visibleArray_.size(); ++x)
353 {
354 visibleArray_[x].resize(indexArray_[x].size());
355 for (size_t y = 0; y < visibleArray_[x].size(); ++y)
356 {
357 for (auto &&e : indexArray_[x][y])
358 {
359 if (e.Confidence() >= ConfidenceThreshold())
360 {
361 visibleArray_[x][y].push_back(e);
362 }
363 else
364 {
365 rejects_[x].push_back(e);
366 }
367 }
368 }
369 }
370 }
371
372 private:
373 std::vector<std::vector<std::vector<PredictionResult>>> indexArray_;
374 std::vector<std::vector<std::vector<PredictionResult>>> visibleArray_;
375 std::vector<std::vector<PredictionResult>> rejects_;
376 double confidenceThreshold_ = 0.0;
377 };
378
379 } /* namespace Testing */
380
383
384 } /* namespace Polimago */
385 CVB_END_INLINE_NS
386} /* namespace Cvb */
ConfusionMatrix(const ClassificationTestResult &res)
Constructor.
Definition confusion_matrix.hpp:94
Classification test result object.
Definition classification_test_result.hpp:27
int NumClasses() const
Number of classes in the sample database on which the test result was calculated.
Definition classification_test_result.hpp:124
std::vector< double > ExampleConfidences() const
Confidences in the classification decision for each sample.
Definition classification_test_result.hpp:176
std::vector< std::vector< double > > ExampleConfidenceDistributions() const
Confidence distributions for each example.
Definition classification_test_result.hpp:186
std::vector< int > TrueClassIndices() const
The real class index for each example.
Definition classification_test_result.hpp:196
std::vector< int > PredictedClassIndices() const
Prediction results for all indices.
Definition classification_test_result.hpp:206
Representation of a confusion matrix.
Definition confusion_matrix.hpp:87
int TotalCorrect() const
Overall number of correctly classified samples.
Definition confusion_matrix.hpp:160
void SetConfidenceThreshold(double threshold)
Set the threshold to be taken into account when determining the confusion matrix.
Definition confusion_matrix.hpp:303
std::vector< PredictionResult > At(int trueClass, int predictedClass) const
Access the results stored in the confusion matrix.
Definition confusion_matrix.hpp:275
std::vector< PredictionResult > Rejects(int classIndex) const
Get the rejects for a given class.
Definition confusion_matrix.hpp:235
int NumClasses() const noexcept
Number of classes in this matrix.
Definition confusion_matrix.hpp:250
int TotalErrors(int classIndex) const
Determine the total number of errors made for a given class.
Definition confusion_matrix.hpp:177
int TotalSamples(int classIndex) const
Determine the total number of samples available for a given class.
Definition confusion_matrix.hpp:107
int TotalRejects() const
Total number of rejected items (i.e. items that have a confidence of less than the currently set thre...
Definition confusion_matrix.hpp:219
double ConfidenceThreshold() const noexcept
Get threshold to be taken into account when determining the confusion matrix.
Definition confusion_matrix.hpp:290
int TotalSamples() const
Return the total sample count.
Definition confusion_matrix.hpp:128
int TotalErrors() const
Determine the total error count.
Definition confusion_matrix.hpp:202
int TotalCorrect(int classIndex) const
Number of correctly classified samples in a given class.
Definition confusion_matrix.hpp:145
ConfusionMatrix(const ClassificationTestResult &res)
Constructor.
Definition confusion_matrix.hpp:94
The information contained in each cell of the confusion matrix.
Definition confusion_matrix.hpp:25
double Confidence() const noexcept
Confidence value of the (best) classification result.
Definition confusion_matrix.hpp:59
int ExampleIndex() const noexcept
The index of the example (with refers to the index in the sample image list from which the test resul...
Definition confusion_matrix.hpp:49
std::vector< double > ConfidenceDistribution() const
Distribution of confidences among the other known classes.
Definition confusion_matrix.hpp:69
int NumExamples() const
Number of examples that contributed to this test result.
Definition test_result_base.hpp:61
Namespace for the Polimago package testing functionality.
Definition classification_test_result.hpp:21
Namespace for the Polimago package.
Definition classification_predictor.hpp:29
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17