CVB++ 14.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{
12CVB_BEGIN_INLINE_NS
13
15namespace Polimago
16{
18namespace Testing
19{
20
22
25{
26public:
27 PredictionResult (const PredictionResult&) = default;
28 PredictionResult& operator= (const PredictionResult&) = default;
29
30private:
31 PredictionResult (const ClassificationTestResult &res, int exampleIndex)
32 : exampleIndex_ (exampleIndex), confidence_ (res.ExampleConfidences()[exampleIndex]),
33 confidenceDistribution_ (res.ExampleConfidenceDistributions()[exampleIndex])
34 {}
35 friend class ConfusionMatrix;
36
37public:
39
43 int ExampleIndex () const noexcept
44 {
45 return exampleIndex_;
46 }
47
49
53 double Confidence () const noexcept
54 {
55 return confidence_;
56 }
57
59
64 {
65 return confidenceDistribution_;
66 }
67
68private:
69 int exampleIndex_;
70 double confidence_;
71 std::vector<double> confidenceDistribution_;
72};
73
75
81{
82public:
84
89 {
90 BuildConfusionMatrix (res);
91 UpdateVisibleMatrix ();
92 }
93
94public:
96
101 int TotalSamples (int classIndex) const
102 {
103 auto numClasses = NumClasses ();
104 if (classIndex >= numClasses)
105 {
106 throw std::out_of_range ("class index out of range");
107 }
108
109 int sum = 0;
110 for (decltype(numClasses) c = 0; c < numClasses; ++c)
111 {
112 sum += static_cast<int>(indexArray_[classIndex][c].size());
113 }
114 return sum;
115 }
116
118
122 int TotalSamples () const
123 {
124 auto numClasses = NumClasses ();
125 int retval = 0;
126 for (decltype(numClasses) i = 0; i < numClasses; ++i)
127 {
128 retval += TotalSamples(i);
129 }
130 return retval;
131 }
132
134
139 int TotalCorrect (int classIndex) const
140 {
141 auto numClasses = NumClasses ();
142 if (classIndex >= numClasses)
143 {
144 throw std::out_of_range ("class index out of range");
145 }
146 return static_cast<int> (At (classIndex, classIndex).size());
147 }
148
150
154 int TotalCorrect () const
155 {
156 auto numClasses = NumClasses ();
157 int sum = 0;
158 for (decltype(numClasses) i = 0; i < numClasses; ++i)
159 {
160 sum += TotalCorrect (i);
161 }
162 return sum;
163 }
164
166
171 int TotalErrors (int classIndex) const
172 {
173 auto numClasses = NumClasses ();
174 if (classIndex >= numClasses)
175 {
176 throw std::out_of_range ("class index out of range");
177 }
178
179 int sum = 0;
180 for (decltype(numClasses) c = 0; c < numClasses; ++c)
181 {
182 sum += static_cast<int>(indexArray_[classIndex][c].size());
183 if (c != classIndex)
184 {
185 sum += static_cast<int> (At (classIndex, c).size());
186 }
187 }
188 return sum;
189 }
190
192
196 int TotalErrors () const
197 {
198 auto numClasses = NumClasses ();
199 int retval = 0;
200 for (decltype(numClasses) i = 0; i < numClasses; ++i)
201 {
202 retval += TotalErrors(i);
203 }
204 return retval;
205 }
206
208
212 int TotalRejects () const
213 {
214 int retval = 0;
215 for (auto && r : rejects_)
216 {
217 retval += static_cast<int>(r.size());
218 }
219 return retval;
220 }
221
223
229 {
230 if (classIndex >= rejects_.size())
231 {
232 throw std::out_of_range ("class index out of range");
233 }
234
235 return rejects_[classIndex];
236 }
237
239
243 int NumClasses () const noexcept
244 {
245 return static_cast<int>(indexArray_.size());
246 }
247
249
268 std::vector<PredictionResult> At (int trueClass, int predictedClass) const
269 {
270 if (trueClass >= NumClasses() || predictedClass >= NumClasses())
271 {
272 throw std::out_of_range ("class index out of range");
273 }
274
275 return visibleArray_[trueClass][predictedClass];
276 }
277
279
283 double ConfidenceThreshold() const noexcept
284 {
285 return confidenceThreshold_;
286 }
287
289
296 void SetConfidenceThreshold(double threshold)
297 {
298 if ((threshold < 0.0) || (threshold > 1.5))
299 {
300 throw std::out_of_range ("confidence threshold value must be within <0.0, 1.5>");
301 }
302 confidenceThreshold_ = threshold;
303 UpdateVisibleMatrix();
304 }
305
306private:
307 void BuildConfusionMatrix (const ClassificationTestResult &res)
308 {
309 auto numClasses = res.NumClasses ();
310 auto numExamples = res.NumExamples ();
311 rejects_.resize (numClasses);
312
313 indexArray_.resize (numClasses);
314 for (auto && indexRow : indexArray_)
315 {
316 indexRow.resize (numClasses);
317 }
318
319 for (decltype(numExamples) i = 0; i < numExamples; ++i)
320 {
321 auto trueIndex = res.TrueClassIndices()[i];
322 auto predictedIndex = res.PredictedClassIndices()[i];
323 indexArray_[trueIndex][predictedIndex].push_back(PredictionResult(res, i));
324 }
325 }
326
327 void UpdateVisibleMatrix ()
328 {
329 for (auto && r : rejects_)
330 {
331 r.clear ();
332 }
333
334 if (ConfidenceThreshold() == 0.0)
335 {
336 visibleArray_ = indexArray_;
337 return;
338 }
339
340 visibleArray_.resize (indexArray_.size());
341 for (auto && visibleRow : visibleArray_)
342 {
343 visibleRow.resize (indexArray_[0].size());
344 }
345 for (size_t x = 0; x < visibleArray_.size (); ++x)
346 {
347 visibleArray_[x].resize (indexArray_[x].size());
348 for (size_t y = 0; y < visibleArray_[x].size (); ++y)
349 {
350 for (auto && e : indexArray_[x][y])
351 {
352 if (e.Confidence () >= ConfidenceThreshold ())
353 {
354 visibleArray_[x][y].push_back (e);
355 }
356 else
357 {
358 rejects_[x].push_back (e);
359 }
360 }
361 }
362 }
363 }
364
365private:
369 double confidenceThreshold_ = 0.0;
370};
371
372
373} /* namespace Testing */
374
375using Testing::PredictionResult;
376using Testing::ConfusionMatrix;
377
378} /* namespace Polimago */
379CVB_END_INLINE_NS
380} /* namespace Cvb */
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:134
std::vector< double > ExampleConfidences() const
Confidences in the classification decision for each sample.
Definition: classification_test_result.hpp:184
std::vector< std::vector< double > > ExampleConfidenceDistributions() const
Confidence distributions for each example.
Definition: classification_test_result.hpp:194
std::vector< int > TrueClassIndices() const
The real class index for each example.
Definition: classification_test_result.hpp:204
std::vector< int > PredictedClassIndices() const
Prediction results for all indices.
Definition: classification_test_result.hpp:214
Representation of a confusion matrix.
Definition: confusion_matrix.hpp:81
int TotalCorrect() const
Overall number of correctly classified samples.
Definition: confusion_matrix.hpp:154
void SetConfidenceThreshold(double threshold)
Set the threshold to be taken into account when determining the confusion matrix.
Definition: confusion_matrix.hpp:296
std::vector< PredictionResult > At(int trueClass, int predictedClass) const
Access the results stored in the confusion matrix.
Definition: confusion_matrix.hpp:268
std::vector< PredictionResult > Rejects(int classIndex) const
Get the rejects for a given class.
Definition: confusion_matrix.hpp:228
int NumClasses() const noexcept
Number of classes in this matrix.
Definition: confusion_matrix.hpp:243
int TotalErrors(int classIndex) const
Determine the total number of errors made for a given class.
Definition: confusion_matrix.hpp:171
int TotalSamples(int classIndex) const
Determine the total number of samples available for a given class.
Definition: confusion_matrix.hpp:101
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:212
double ConfidenceThreshold() const noexcept
Get threshold to be taken into account when determining the confusion matrix.
Definition: confusion_matrix.hpp:283
int TotalSamples() const
Return the total sample count.
Definition: confusion_matrix.hpp:122
int TotalErrors() const
Determine the total error count.
Definition: confusion_matrix.hpp:196
int TotalCorrect(int classIndex) const
Number of correctly classified samples in a given class.
Definition: confusion_matrix.hpp:139
ConfusionMatrix(const ClassificationTestResult &res)
Constructor.
Definition: confusion_matrix.hpp:88
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:53
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:43
std::vector< double > ConfidenceDistribution() const
Distribution of confidences among the other known classes.
Definition: confusion_matrix.hpp:63
int NumExamples() const
Number of examples that contributed to this test result.
Definition: test_result_base.hpp:67
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24