Brush C++ API
A flexible interpretable machine learning framework
Loading...
Searching...
No Matches
scorer.h
Go to the documentation of this file.
1#ifndef SCORER_H
2#define SCORER_H
3
4#include "metrics.h"
5#include "../util/error.h"
6#include "../types.h"
7
8// code to evaluate GP programs.
9namespace Brush{
10
11using namespace Pop;
12
13namespace Eval{
14
15
16template <ProgramType P>
17class Scorer
18{
19
20using RetType =
21 typename std::conditional_t<P == PT::Regressor, ArrayXf,
22 std::conditional_t<P == PT::Representer, ArrayXXf, ArrayXf
23 >>;
24
25typedef float (*funcPointer)(const VectorXf&,
26 const VectorXf&,
27 VectorXf&,
28 const vector<float>&);
29public:
30 // map the string into a function to be called when calculating the score
31 std::map<string, funcPointer> score_hash;
32 string scorer;
33
34 // TODO: add more scores, include them here, add to score_hash
35 Scorer(string scorer="mse") {
36 score_hash["mse"] = &mse;
37
38 this->set_scorer(scorer);
39 };
40
41 void set_scorer(string scorer){ this->scorer = scorer; };
42 string get_scorer(){return this->scorer; };
43
44 /* void set_scorer(string scorer); */
45 float score(const VectorXf& y_true, const VectorXf& y_pred,
46 VectorXf& loss, const vector<float>& w)
47 {
48 // loss is an array passed by reference to store each prediction (used in lexicase)
49 // weights are used to give more or less importance for a given sample.
50 // Every scorer must have the same function signature, but arent required to use all info
51
52 if ( score_hash.find(this->scorer) == score_hash.end() )
53 {
54 HANDLE_ERROR_THROW("Scoring function '" + this->scorer + "' not defined");
55 return 0.0;
56 }
57 else
58 {
59 return score_hash.at(this->scorer)(y_true, y_pred, loss, w);
60 }
61 };
62
63 float score(Individual<P>& ind, Dataset& data,
64 VectorXf& loss, const Parameters& params)
65 {
66 RetType y_pred = ind.predict(data);
67 return score(data.y, y_pred, loss, params.class_weights);
68 }
69};
70
71
72// TODO: improve this so we dont have a lot of different declarations
73template <ProgramType P>
74 requires( P == PT::BinaryClassifier)
76{
77
78using RetType = ArrayXf;
79
80typedef float (*funcPointer)(const VectorXf&,
81 const VectorXf&,
82 VectorXf&,
83 const vector<float>&);
84public:
85 // map the string into a function to be called when calculating the score
86 std::map<string, funcPointer> score_hash;
87 string scorer;
88
89 Scorer(string scorer="log") {
90 score_hash["log"] = &mean_log_loss;
91 score_hash["average_precision_score"] = &average_precision_score;
92 score_hash["accuracy"] = &zero_one_loss;
93 score_hash["balanced_accuracy"] = &bal_zero_one_loss;
94 score_hash["precision"] = &precision_score;
95 score_hash["recall"] = &recall_score;
96 score_hash["roc_auc"] = &roc_auc_score;
97
98 this->set_scorer(scorer);
99 };
100
101 void set_scorer(string scorer){ this->scorer = scorer; };
102 string get_scorer(){return this->scorer; };
103
104 /* void set_scorer(string scorer); */
105 float score(const VectorXf& y_true, const VectorXf& y_pred,
106 VectorXf& loss, const vector<float>& w)
107 {
108 if ( score_hash.find(this->scorer) == score_hash.end() )
109 {
110 // not found
111 HANDLE_ERROR_THROW("Scoring function '" + this->scorer
112 + "' not defined");
113 return 0.0;
114 }
115 else
116 {
117 // found
118 return score_hash.at(this->scorer)(y_true, y_pred, loss, w);
119 }
120 };
121
122 float score(Individual<P>& ind, Dataset& data,
123 VectorXf& loss, const Parameters& params)
124 {
125 RetType y_pred = ind.predict_proba(data); // .template cast<float>();
126
127 vector<float> class_weights = {};
128
129 // calculate class weights based on current data --- instead of using a pre-calculated value.
130 // This is only true for the scoring. For other usages of class weights, then
131 // the training data is used.
132 if (params.class_weights_type == "support")
133 {
134 class_weights.resize(params.n_classes);
135 for (unsigned i = 0; i < params.n_classes; ++i){
136 // weighting by support
137 int support = (data.y.cast<int>().array() == i).count();
138
139 if (support==0)
140 class_weights.at(i) = 0.0f;
141 else
142 class_weights.at(i) = float(data.y.size()) / float(params.n_classes * support);
143 }
144 }
145 else // else it is either unbalanced or user_defined
146 {
147 // if unbalanced, class_weights is empty. if user_defined,
148 // then we should use the provided values anyways
149 class_weights = params.class_weights;
150 }
151
152 return score(data.y, y_pred, loss, class_weights);
153 }
154};
155
156template <ProgramType P>
157 requires(P == PT::MulticlassClassifier)
158class Scorer<P>
159{
160
161using RetType = ArrayXXf;
162
163typedef float (*funcPointer)(const VectorXf&,
164 const ArrayXXf&,
165 VectorXf&,
166 const vector<float>&);
167public:
168 // map the string into a function to be called when calculating the score
169 std::map<string, funcPointer> score_hash;
170 string scorer;
171
172 // TODO: I need to test this stuff
173 Scorer(string scorer="multi_log") {
174 score_hash["multi_log"] = &mean_multi_log_loss;
175 score_hash["accuracy"] = &multi_zero_one_loss;
176 score_hash["balanced_accuracy"] = &multi_bal_zero_one_loss;
177 score_hash["precision"] = &multi_precision_score;
178 score_hash["recall"] = &multi_recall_score;
179 score_hash["roc_auc"] = &multi_roc_auc_score;
180 score_hash["average_precision_score"] = &multi_average_precision_score;
181
182 this->set_scorer(scorer);
183 };
184
185 void set_scorer(string scorer){ this->scorer = scorer; };
186 string get_scorer(){return this->scorer; };
187
188 /* void set_scorer(string scorer); */
189 float score(const VectorXf& y_true, const ArrayXXf& y_pred,
190 VectorXf& loss, const vector<float>& w)
191 {
192 // loss is an array passed by reference to store each prediction (used in lexicase)
193 // weights are used to give more or less importance for a given sample.
194 // Every scorer must have the same function signature, but arent required to use all info
195
196 if ( score_hash.find(this->scorer) == score_hash.end() )
197 {
198 // not found
199 HANDLE_ERROR_THROW("Scoring function '" + this->scorer
200 + "' not defined");
201 return 0.0;
202 }
203 else
204 {
205 // found
206 return score_hash.at(this->scorer)(y_true, y_pred, loss, w);
207 }
208 };
209
210 float score(Individual<P>& ind, Dataset& data,
211 VectorXf& loss, const Parameters& params)
212 {
213 RetType y_pred = ind.predict_proba(data); // .template cast<float>();
214
215 vector<float> class_weights = {};
216 if (params.class_weights_type == "support")
217 {
218 class_weights.resize(params.n_classes);
219 for (unsigned i = 0; i < params.n_classes; ++i){
220 // weighting by support
221 int support = (data.y.cast<int>().array() == i).count();
222
223 if (support==0)
224 class_weights.at(i) = 0.0;
225 else
226 class_weights.at(i) = float(data.y.size()) / float(params.n_classes * support);
227 }
228 } // or else it is either unbalanced or user_defined
229 else {
230 class_weights = params.class_weights;
231 }
232
233 return score(data.y, y_pred, loss, class_weights);
234 }
235};
236
237}
238}
239#endif
void set_scorer(string scorer)
Definition scorer.h:101
float(*) funcPointer(const VectorXf &, const VectorXf &, VectorXf &, const vector< float > &)
Definition scorer.h:80
float score(Individual< P > &ind, Dataset &data, VectorXf &loss, const Parameters &params)
Definition scorer.h:122
float score(const VectorXf &y_true, const ArrayXXf &y_pred, VectorXf &loss, const vector< float > &w)
Definition scorer.h:189
Scorer(string scorer="multi_log")
Definition scorer.h:173
Scorer(string scorer="log")
Definition scorer.h:89
std::map< string, funcPointer > score_hash
Definition scorer.h:86
float score(const VectorXf &y_true, const VectorXf &y_pred, VectorXf &loss, const vector< float > &w)
Definition scorer.h:105
string get_scorer()
Definition scorer.h:42
void set_scorer(string scorer)
Definition scorer.h:41
float(*) funcPointer(const VectorXf &, const VectorXf &, VectorXf &, const vector< float > &)
Definition scorer.h:25
float score(Individual< P > &ind, Dataset &data, VectorXf &loss, const Parameters &params)
Definition scorer.h:63
typename std::conditional_t< P==PT::Regressor, ArrayXf, std::conditional_t< P==PT::Representer, ArrayXXf, ArrayXf > > RetType
Definition scorer.h:20
Scorer(string scorer="mse")
Definition scorer.h:35
std::map< string, funcPointer > score_hash
Definition scorer.h:31
float score(const VectorXf &y_true, const VectorXf &y_pred, VectorXf &loss, const vector< float > &w)
Definition scorer.h:45
auto predict(const Dataset &data)
Definition individual.h:104
auto predict_proba(const Dataset &d)
Definition individual.h:113
holds variable type data.
Definition data.h:51
ArrayXf y
length N array, the target label
Definition data.h:82
#define HANDLE_ERROR_THROW(err)
Definition error.h:27
float multi_zero_one_loss(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Accuracy for multi-classification.
Definition metrics.cpp:438
float precision_score(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Precision for binary classification (threshold 0.5, positive label 1).
Definition metrics.cpp:360
float zero_one_loss(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Accuracy for binary classification.
Definition metrics.cpp:75
float mean_log_loss(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
log loss
Definition metrics.cpp:47
float multi_recall_score(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Macro-averaged recall for multi-classification.
Definition metrics.cpp:509
float mean_multi_log_loss(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Calculates the mean multinomial log loss between the predicted probabilities and the true labels.
Definition metrics.cpp:417
float average_precision_score(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Calculates the average precision score between the predicted probabilities and the true labels.
Definition metrics.cpp:343
float mse(const VectorXf &y, const VectorXf &yhat, VectorXf &loss, const vector< float > &class_weights)
mean squared error
Definition metrics.cpp:11
float multi_bal_zero_one_loss(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Balanced accuracy for multi-classification.
Definition metrics.cpp:465
float recall_score(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Recall for binary classification (threshold 0.5, positive label 1).
Definition metrics.cpp:374
float multi_roc_auc_score(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Macro-averaged one-vs-rest AUROC for multi-classification.
Definition metrics.cpp:515
float multi_precision_score(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Macro-averaged precision for multi-classification.
Definition metrics.cpp:503
float multi_average_precision_score(const VectorXf &y, const ArrayXXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Macro-averaged one-vs-rest average precision for multi-classification.
Definition metrics.cpp:537
float bal_zero_one_loss(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Balanced accuracy for binary classification.
Definition metrics.cpp:102
float roc_auc_score(const VectorXf &y, const VectorXf &predict_proba, VectorXf &loss, const vector< float > &class_weights)
Area under the ROC curve for binary classification.
Definition metrics.cpp:386
< nsga2 selection operator for getting the front
Definition bandit.cpp:3
vector< float > class_weights
weights for each class
Definition params.h:69
unsigned int n_classes
Definition params.h:76
string class_weights_type
Definition params.h:71