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: // TODO: make these private (and work with nlohman json)
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 // TODO: replace occurences of program.fit with these (also predict and predict_proba)
68 Individual<T> &fit(const Dataset& data) {
69 program.fit(data);
70 this->is_fitted_ = true;
71 return *this;
72 };
73 Individual<T> &fit(const Ref<const ArrayXXf>& X, const Ref<const ArrayXf>& y)
74 {
75 Dataset d(X,y);
76 return fit(d);
77 };
78
79 auto predict(const Dataset& data) { return program.predict(data); };
80 auto predict(const Ref<const ArrayXXf>& X)
81 {
82 Dataset d(X);
83 return predict(d);
84 };
85
86 template <ProgramType P = T>
87 requires((P == PT::BinaryClassifier) || (P == PT::MulticlassClassifier))
88 auto predict_proba(const Dataset &d) { return program.predict_proba(d); };
89 template <ProgramType P = T>
90 requires((P == PT::BinaryClassifier) || (P == PT::MulticlassClassifier))
91 auto predict_proba(const Ref<const ArrayXXf>& X)
92 {
93 Dataset d(X);
94 return predict_proba(d);
95 };
96
97 // just getters
98 unsigned int get_size() const { return program.size(); };
99 unsigned int get_depth() const { return program.depth(); };
100 unsigned int get_complexity() const { return program.complexity(); };
101 unsigned int get_linear_complexity() const { return program.linear_complexity(); };
103
104 string get_model(string fmt="compact", bool pretty=false) {
105 return program.get_model(fmt, pretty); };
106 string get_dot_model(string extras="") {
107 return program.get_dot_model(extras); };
108
109 void set_fitness(Fitness &f) { fitness=f; };
111
112 void set_variation(string v) { variation=v; };
113 string get_variation() const { return variation; };
114
115 bool get_is_fitted() const { return this->is_fitted_; };
116 void set_is_fitted(bool fitted) { this->is_fitted_ = fitted; };
117
118 void set_sampled_nodes(const vector<Node>& nodes) { sampled_nodes = nodes; };
119 vector<Node> get_sampled_nodes() const { return sampled_nodes; };
120
121 void set_id(unsigned i){id = i;};
122 void set_parents(const vector<Individual<T>>& parents){
123 parent_id.clear();
124 for (const auto& p : parents)
125 parent_id.push_back(p.id);
126 };
127 void set_parents(const vector<unsigned>& parents){ parent_id = parents; };
128
129 // TODO: USE setters and getters intead of accessing it directly
130 // template<ProgramType T>
131 // void Individual<T>::set_objectives(const vector<string>& objectives)
132
133 // Static map for weights associated with strings.
134 // this will determine each fitness metric to be a min/max problem.
135 // generic error metric: by default log and multi_log if it is a
136 // classification problem, and MSE if it is a regression (so its always
137 // a minimization by default, thus "scorer" has weight -1.0)
138 inline static std::map<std::string, float> weightsMap = {
139 {"complexity", -1.0},
140 {"linear_complexity", -1.0},
141 {"size", -1.0},
142 {"mse", -1.0},
143 {"log", -1.0},
144 {"multi_log", -1.0},
145 {"average_precision_score", +1.0},
146 {"balanced_accuracy", +1.0},
147 {"accuracy", +1.0}
148 // {"scorer", -1.0}
149 };
150
151 vector<string> get_objectives() const { return objectives; };
152 void set_objectives(vector<string> objs){
153 objectives=objs;
154
155 vector<float> weights;
156 weights.resize(0);
157 for (const auto& obj : objectives) {
158 // TODO: do i need to use find or this can be done directly?
159 auto it = weightsMap.find(obj);
160 if (it != weightsMap.end()) {
161 weights.push_back(it->second);
162 } else {
163 throw std::runtime_error(
164 "Unknown metric used as fitness. Value was " + obj);
165 }
166 }
167
168 fitness.set_weights(weights);
169 };
170};
171
172
173// serialization for Individual
174template<ProgramType T>
175void to_json(json &j, const Individual<T> &p)
176{
177 j = json{
178 {"program", p.program},
179 {"fitness", p.fitness},
180 {"id", p.id},
181 {"parent_id", p.parent_id},
182 {"objectives", p.objectives},
183 {"is_fitted_", p.is_fitted_},
184 {"variation", p.variation}\
185 };
186}
187
188template<ProgramType T>
189void from_json(const json &j, Individual<T>& p)
190{// TODO: figure out if this works with private attributes and try to actually make them private (and use getters and setters)
191 j.at("program").get_to( p.program );
192 j.at("fitness").get_to( p.fitness );
193 j.at("id").get_to( p.id );
194 j.at("parent_id").get_to( p.parent_id );
195 j.at("objectives").get_to( p.objectives );
196 j.at("is_fitted_").get_to( p.is_fitted_ );
197 j.at("variation").get_to( p.variation );\
198}
199} // Pop
200} // Brush
201
202#endif
holds variable type data.
Definition data.h:51
static std::map< std::string, float > weightsMap
Definition individual.h:138
void set_is_fitted(bool fitted)
Definition individual.h:116
unsigned int get_complexity() const
Definition individual.h:100
string get_model(string fmt="compact", bool pretty=false)
Definition individual.h:104
auto predict(const Dataset &data)
Definition individual.h:79
void set_fitness(Fitness &f)
Definition individual.h:109
auto predict_proba(const Dataset &d)
Definition individual.h:88
Individual< T > & fit(const Dataset &data)
Definition individual.h:68
void set_variation(string v)
Definition individual.h:112
void set_sampled_nodes(const vector< Node > &nodes)
Definition individual.h:118
unsigned int get_size() const
Definition individual.h:98
Program< T > & get_program()
Definition individual.h:102
void set_id(unsigned i)
Definition individual.h:121
vector< Node > get_sampled_nodes() const
Definition individual.h:119
Fitness & get_fitness()
Definition individual.h:110
Individual< T > & fit(const Ref< const ArrayXXf > &X, const Ref< const ArrayXf > &y)
Definition individual.h:73
string get_variation() const
Definition individual.h:113
void set_parents(const vector< unsigned > &parents)
set parent ids using parents
Definition individual.h:127
string get_dot_model(string extras="")
Definition individual.h:106
vector< string > get_objectives() const
Definition individual.h:151
auto predict_proba(const Ref< const ArrayXXf > &X)
Definition individual.h:91
void set_objectives(vector< string > objs)
Definition individual.h:152
void set_parents(const vector< Individual< T > > &parents)
Definition individual.h:122
Individual(Program< T > &prg)
Definition individual.h:48
unsigned int get_depth() const
Definition individual.h:99
auto predict(const Ref< const ArrayXXf > &X)
Definition individual.h:80
unsigned int get_linear_complexity() const
Definition individual.h:101
void init(SearchSpace &ss, const Parameters &params)
Definition individual.h:52
bool get_is_fitted() const
Definition individual.h:115
void to_json(json &j, const Individual< T > &p)
Definition individual.h:175
void from_json(const json &j, Individual< T > &p)
Definition individual.h:189
< nsga2 selection operator for getting the front
Definition bandit.cpp:4
Represents the fitness of an individual in the Brush namespace.
Definition fitness.h:25
vector< string > get_objectives() const
Definition params.h:150
An individual program, a.k.a. model.
Definition program.h:50
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.