Brush C++ API
A flexible interpretable machine learning framework
Loading...
Searching...
No Matches
individual.h
Go to the documentation of this file.
1#ifndef INDIVIDUAL_H
2#define INDIVIDUAL_H
3
5#include "fitness.h"
6
7#include <functional>
8
9using namespace nlohmann;
10
11namespace Brush{
12namespace Pop{
13
14template<ProgramType T>
16public:
18
19 // store just info that we dont have a getter. size, depth, complexity: they can all be obtained with program.<function here>
20
21 // error is the aggregation of error vector, and can be user sppecified
22
23 // this flag is used to avoid re-fitting an individual. the program is_fitted_ flag is used to perform checks (like in predict with weights). They are two different things and I think I;ll keep this way (individual is just a container to keep program and fitness together)
24 bool is_fitted_ = false;
25
26 // archive utility (and also keep track of evolution) (this is meaningful only
27 // if variation is done using the vary() function)
28 unsigned id;
29 vector<unsigned> parent_id;
30
31 // storing what changed in relation to parent inside variation
32 string variation = "born"; // spontanegous generation (born), crossover, or which type of mutation
33 vector<Node> sampled_nodes = {}; // nodes that were sampled in mutation
34
35 VectorXf error;
36
38
39 vector<string> objectives;
40
41
43 {
44 objectives = {"scorer", "linear_complexity"};
45 id = 0; // unsigned
46 };
47
49 program = prg;
50 };
51
52 void init(SearchSpace& ss, const Parameters& params)
53 {
54 program = ss.make_program<Program<T>>(params, 0, 0);
55
56 // overriding the objectives with the ones from params (to replace
57 // the generic "scorer" by the actual scorer set in the params object)
58 objectives = params.get_objectives();
59
60 // If different from zero, then the program is created with a fixed depth and size.
61 // If zero, it samples the value
62 // program = SS.make_program<T>(params, params.max_depth, params.max_size);
63
64 variation = "born";
65 };
66
67 Individual<T> &fit(const Dataset& data) {
68 program.fit(data);
69 this->is_fitted_ = true;
70 return *this;
71 };
72 Individual<T> &fit(const Ref<const ArrayXXf>& X, const Ref<const ArrayXf>& y)
73 {
74 Dataset d(X,y);
75 return fit(d);
76 };
77
85 {
86 program.replace_program(new_program);
87 this->is_fitted_ = false;
88 fitness.clearValues();
89 return *this;
90 };
91
99 {
100 Program<T> new_program = j;
101 return replace_program(new_program);
102 };
103
104 auto predict(const Dataset& data) { return program.predict(data); };
105 auto predict(const Ref<const ArrayXXf>& X)
106 {
107 Dataset d(X);
108 return predict(d);
109 };
110
111 template <ProgramType P = T>
112 requires((P == PT::BinaryClassifier) || (P == PT::MulticlassClassifier))
113 auto predict_proba(const Dataset &d) { return program.predict_proba(d); };
114 template <ProgramType P = T>
115 requires((P == PT::BinaryClassifier) || (P == PT::MulticlassClassifier))
116 auto predict_proba(const Ref<const ArrayXXf>& X)
117 {
118 Dataset d(X);
119 return predict_proba(d);
120 };
121
122 // just getters
123 unsigned int get_size() const { return program.size(); };
124 unsigned int get_depth() const { return program.depth(); };
125 unsigned int get_complexity() const { return program.complexity(); };
126 unsigned int get_linear_complexity() const { return program.linear_complexity(); };
128
129 string get_model(string fmt="compact", bool pretty=false) {
130 return program.get_model(fmt, pretty); };
131 string get_dot_model(string extras="") {
132 return program.get_dot_model(extras); };
133
134 void set_fitness(Fitness &f) { fitness=f; };
136
137 void set_variation(string v) { variation=v; };
138 string get_variation() const { return variation; };
139
140 bool get_is_fitted() const { return this->is_fitted_; };
141 void set_is_fitted(bool fitted) { this->is_fitted_ = fitted; };
142
143 void set_sampled_nodes(const vector<Node>& nodes) { sampled_nodes = nodes; };
144 vector<Node> get_sampled_nodes() const { return sampled_nodes; };
145
146 unsigned int get_id(){ return id;};
147 void set_id(unsigned i){id = i;};
148 void set_parents(const vector<Individual<T>>& parents){
149 parent_id.clear();
150 for (const auto& p : parents)
151 parent_id.push_back(p.id);
152 };
153 void set_parents(const vector<unsigned>& parents){ parent_id = parents; };
154
155 // template<ProgramType T>
156 // void Individual<T>::set_objectives(const vector<string>& objectives)
157
158 // Static map for weights associated with strings.
159 // this will determine each fitness metric to be a min/max problem.
160 // generic error metric: by default log and multi_log if it is a
161 // classification problem, and MSE if it is a regression (so its always
162 // a minimization by default, thus "scorer" has weight -1.0)
163 inline static std::map<std::string, float> weightsMap = {
164 {"complexity", -1.0},
165 {"linear_complexity", -1.0},
166 {"size", -1.0},
167 {"mse", -1.0},
168 {"log", -1.0},
169 {"multi_log", -1.0},
170 {"average_precision_score", +1.0},
171 {"balanced_accuracy", +1.0},
172 {"accuracy", +1.0}
173 // {"scorer", -1.0}
174 };
175
176 vector<string> get_objectives() const { return objectives; };
177 void set_objectives(vector<string> objs){
178 objectives=objs;
179
180 vector<float> weights;
181 weights.resize(0);
182 for (const auto& obj : objectives) {
183 auto it = weightsMap.find(obj);
184 if (it != weightsMap.end()) {
185 weights.push_back(it->second);
186 } else {
187 throw std::runtime_error(
188 "Unknown metric used as fitness. Value was " + obj);
189 }
190 }
191
192 fitness.set_weights(weights);
193 };
194};
195
196
197// serialization for Individual
198template<ProgramType T>
199void to_json(json &j, const Individual<T> &p)
200{
201 // error and sampled nodes are not being serialized
202 j = json{
203 {"program", p.program},
204 {"fitness", p.fitness},
205 {"id", p.id},
206 {"parent_id", p.parent_id},
207 {"objectives", p.objectives},
208 {"is_fitted_", p.is_fitted_},
209 {"variation", p.variation}
210 };
211}
212
213template<ProgramType T>
214void from_json(const json &j, Individual<T>& p)
215{
216 j.at("program").get_to( p.program );
217 j.at("fitness").get_to( p.fitness );
218 j.at("id").get_to( p.id );
219 j.at("parent_id").get_to( p.parent_id );
220 j.at("objectives").get_to( p.objectives );
221 j.at("is_fitted_").get_to( p.is_fitted_ );
222 j.at("variation").get_to( p.variation );
223}
224} // Pop
225} // Brush
226
227#endif
holds variable type data.
Definition data.h:51
static std::map< std::string, float > weightsMap
Definition individual.h:163
void set_is_fitted(bool fitted)
Definition individual.h:141
unsigned int get_id()
Definition individual.h:146
unsigned int get_complexity() const
Definition individual.h:125
Individual< T > & replace_program(const Program< T > &new_program)
Replace the current program with a new program, invalidating fitness.
Definition individual.h:84
string get_model(string fmt="compact", bool pretty=false)
Definition individual.h:129
auto predict(const Dataset &data)
Definition individual.h:104
void set_fitness(Fitness &f)
Definition individual.h:134
auto predict_proba(const Dataset &d)
Definition individual.h:113
Individual< T > & fit(const Dataset &data)
Definition individual.h:67
void set_variation(string v)
Definition individual.h:137
void set_sampled_nodes(const vector< Node > &nodes)
Definition individual.h:143
unsigned int get_size() const
Definition individual.h:123
Program< T > & get_program()
Definition individual.h:127
void set_id(unsigned i)
Definition individual.h:147
vector< Node > get_sampled_nodes() const
Definition individual.h:144
Fitness & get_fitness()
Definition individual.h:135
Individual< T > & fit(const Ref< const ArrayXXf > &X, const Ref< const ArrayXf > &y)
Definition individual.h:72
string get_variation() const
Definition individual.h:138
void set_parents(const vector< unsigned > &parents)
set parent ids using parents
Definition individual.h:153
string get_dot_model(string extras="")
Definition individual.h:131
vector< string > get_objectives() const
Definition individual.h:176
auto predict_proba(const Ref< const ArrayXXf > &X)
Definition individual.h:116
void set_objectives(vector< string > objs)
Definition individual.h:177
void set_parents(const vector< Individual< T > > &parents)
Definition individual.h:148
Individual(Program< T > &prg)
Definition individual.h:48
unsigned int get_depth() const
Definition individual.h:124
auto predict(const Ref< const ArrayXXf > &X)
Definition individual.h:105
unsigned int get_linear_complexity() const
Definition individual.h:126
Individual< T > & replace_program(const json &j)
Replace the current program from a JSON representation, invalidating fitness.
Definition individual.h:98
void init(SearchSpace &ss, const Parameters &params)
Definition individual.h:52
bool get_is_fitted() const
Definition individual.h:140
void to_json(json &j, const Individual< T > &p)
Definition individual.h:199
void from_json(const json &j, Individual< T > &p)
Definition individual.h:214
< nsga2 selection operator for getting the front
Definition bandit.cpp:3
Represents the fitness of an individual in the Brush namespace.
Definition fitness.h:25
vector< string > get_objectives() const
Definition params.h:148
An individual program, a.k.a. model.
Definition program.h:49
Holds a search space, consisting of operations and terminals and functions, and methods to sample tha...
PT make_program(const Parameters &params, int max_d=0, int max_size=0)
Makes a random program.