1 /**
2 * @file core/cv/metrics/f1_impl.hpp
3 * @author Kirill Mishchenko
4 *
5 * Implementation of the class F1.
6 *
7 * mlpack is free software; you may redistribute it and/or modify it under the
8 * terms of the 3-clause BSD license. You should have received a copy of the
9 * 3-clause BSD license along with mlpack. If not, see
10 * http://www.opensource.org/licenses/BSD-3-Clause for more information.
11 */
12 #ifndef MLPACK_CORE_CV_METRICS_F1_IMPL_HPP
13 #define MLPACK_CORE_CV_METRICS_F1_IMPL_HPP
14
15 #include <mlpack/core/cv/metrics/accuracy.hpp>
16 #include <mlpack/core/cv/metrics/facilities.hpp>
17
18 namespace mlpack {
19 namespace cv {
20
21 template<AverageStrategy AS, size_t PC /* PositiveClass */>
22 template<typename MLAlgorithm, typename DataType>
Evaluate(MLAlgorithm & model,const DataType & data,const arma::Row<size_t> & labels)23 double F1<AS, PC>::Evaluate(MLAlgorithm& model,
24 const DataType& data,
25 const arma::Row<size_t>& labels)
26 {
27 return Evaluate<AS>(model, data, labels);
28 }
29
30 template<AverageStrategy AS, size_t PC /* PositiveClass */>
31 template<AverageStrategy _AS, typename MLAlgorithm, typename DataType, typename>
Evaluate(MLAlgorithm & model,const DataType & data,const arma::Row<size_t> & labels)32 double F1<AS, PC>::Evaluate(MLAlgorithm& model,
33 const DataType& data,
34 const arma::Row<size_t>& labels)
35 {
36 AssertSizes(data, labels, "F1<Binary>::Evaluate()");
37
38 arma::Row<size_t> predictedLabels;
39 model.Classify(data, predictedLabels);
40
41 size_t tp = arma::sum((labels == PC) % (predictedLabels == PC));
42 size_t numberOfPositivePredictions = arma::sum(predictedLabels == PC);
43 size_t numberOfPositiveClassInstances = arma::sum(labels == PC);
44
45 double precision = double(tp) / numberOfPositivePredictions;
46 double recall = double(tp) / numberOfPositiveClassInstances;
47
48 return (precision + recall == 0.0) ? 0.0 :
49 2.0 * precision * recall / (precision + recall);
50 }
51
52 template<AverageStrategy AS, size_t PC /* PositiveClass */>
53 template<AverageStrategy _AS, typename MLAlgorithm, typename DataType, typename,
54 typename>
Evaluate(MLAlgorithm & model,const DataType & data,const arma::Row<size_t> & labels)55 double F1<AS, PC>::Evaluate(MLAlgorithm& model,
56 const DataType& data,
57 const arma::Row<size_t>& labels)
58 {
59 AssertSizes(data, labels, "F1<Micro>::Evaluate()");
60
61 // Microaveraged F1 is really the same as microaveraged precision and
62 // microaveraged recall, which are in turn the same as accuracy.
63 return Accuracy::Evaluate(model, data, labels);
64 }
65
66 template<AverageStrategy AS, size_t PC /* PositiveClass */>
67 template<AverageStrategy _AS, typename MLAlgorithm, typename DataType, typename,
68 typename, typename>
Evaluate(MLAlgorithm & model,const DataType & data,const arma::Row<size_t> & labels)69 double F1<AS, PC>::Evaluate(MLAlgorithm& model,
70 const DataType& data,
71 const arma::Row<size_t>& labels)
72 {
73 AssertSizes(data, labels, "F1<Macro>::Evaluate()");
74
75 arma::Row<size_t> predictedLabels;
76 model.Classify(data, predictedLabels);
77
78 size_t numClasses = arma::max(labels) + 1;
79
80 arma::vec f1s = arma::vec(numClasses);
81 for (size_t c = 0; c < numClasses; ++c)
82 {
83 size_t tp = arma::sum((labels == c) % (predictedLabels == c));
84 size_t positivePredictions = arma::sum(predictedLabels == c);
85 size_t positiveLabels = arma::sum(labels == c);
86
87 double precision = double(tp) / positivePredictions;
88 double recall = double(tp) / positiveLabels;
89 f1s(c) = (precision + recall == 0.0) ? 0.0 :
90 2.0 * precision * recall / (precision + recall);
91 }
92
93 return arma::mean(f1s);
94 }
95
96 } // namespace cv
97 } // namespace mlpack
98
99 #endif
100