37typedef tree<Node>::pre_order_iterator
Iter;
38typedef tree<Node>::post_order_iterator
PostIter;
75 std::optional<std::reference_wrapper<SearchSpace>>
SSref;
78 Program(
const std::reference_wrapper<SearchSpace> s,
const tree<Node> t)
81 SSref = std::optional<std::reference_wrapper<SearchSpace>>{s};
88 SSref = std::optional<std::reference_wrapper<SearchSpace>>{s};
94 auto head =
Tree.begin();
96 return head.node->get_complexity();
102 auto head =
Tree.begin();
104 return head.node->get_linear_complexity();
110 int size(
bool include_weight=
true)
const{
111 auto head =
Tree.begin();
113 return head.node->get_size(include_weight);
123 return top.node->get_size(include_weight);
131 return 1+
Tree.max_depth();
139 return 1+
Tree.max_depth(top);
147 return 1+
Tree.depth(top);
153 this->is_fitted_ =
true;
159 template <
typename R,
typename W>
165 return Tree.begin().node->predict<R>(d, weights);
170 float const * wptr = weights.data();
182 template <
typename R = RetType>
195 template <
typename R = RetType>
208 template <
typename R = RetType>
220 template <PT P = PType>
253 template <PT P = PType>
275 const auto& node = i.node->data;
278 || (node.get_is_weighted() &&
IsWeighable(node.node_type)) )
295 const auto& node = t.node->data;
297 || (node.get_is_weighted() &&
IsWeighable(node.node_type)) )
321 auto& node = i.node->data;
323 || (node.get_is_weighted() &&
IsWeighable(node.node_type)) )
348 auto tree_iter =
Tree.begin();
350 std::for_each(
Tree.begin(),
Tree.end(),
352 auto d = Tree.depth(tree_iter);
353 std::advance(tree_iter, 1);
355 if (skip_leaves && IsLeaf(n.node_type))
374 auto tree_iter =
Tree.begin();
376 std::for_each(
Tree.begin(),
Tree.end(),
378 auto d = Tree.depth(tree_iter);
379 std::advance(tree_iter, 1);
400 string get_model(
string fmt=
"compact",
bool pretty=
false)
const
402 auto head =
Tree.begin();
404 return head.node->get_tree_model(pretty);
407 return head.node->get_model(pretty);
420 string out =
"digraph G {\n";
421 if (! extras.empty())
422 out += fmt::format(
"{}\n", extras);
424 auto get_id = [](
const auto& n){
426 return n->data.get_name(
false);
428 return fmt::format(
"{}",fmt::ptr(n)).substr(2);
431 std::map<string, unsigned int> node_count;
433 for (
Iter iter =
Tree.begin(); iter!=
Tree.end(); iter++)
435 const auto& parent = iter.node;
438 string parent_id = get_id(parent);
448 if (i==0 && parent->data.get_is_weighted())
450 out +=
"y [shape=box];\n";
451 out += fmt::format(
"y -> \"{}\" [label=\"{:.2f}\"];\n",
460 string node_label = parent->data.get_name(is_constant);
463 node_label = fmt::format(
"{}>{:.2f}?", parent->data.get_feature(), parent->data.W);
466 node_label = fmt::format(
"Add");
468 out += fmt::format(
"\"{}\" [label=\"{}\"];\n", parent_id, node_label);
471 auto kid = iter.node->first_child;
472 for (
int j = 0; j < iter.number_of_children(); ++j)
474 string edge_label=
"";
475 string head_label=
"";
476 string tail_label=
"";
477 bool use_head_tail_labels =
false;
479 string kid_id = get_id(kid);
483 if (kid->data.get_is_weighted()
487 edge_label = fmt::format(
"{:.2f}",kid->data.W);
491 use_head_tail_labels=
true;
493 tail_label = fmt::format(
">{:.2f}",parent->data.W);
499 head_label=edge_label;
502 use_head_tail_labels=
true;
509 head_label = edge_label;
512 if (use_head_tail_labels){
513 out += fmt::format(
"\"{}\" -> \"{}\" [headlabel=\"{}\",taillabel=\"{}\"];\n",
521 out += fmt::format(
"\"{}\" -> \"{}\" [label=\"{}\"];\n",
527 kid = kid->next_sibling;
533 out += fmt::format(
"\"{}\" -> \"{}\" [label=\"\"];\n",
539 out += fmt::format(
"\"{}\" [label=\"{:.2f}\"];\n",
554 vector<Node> linear_program;
556 linear_program.push_back(i.node->data);
557 return linear_program;
568template<ProgramType PType>
575 WO.update((*
this), d);
582template<ProgramType PType>
588template<ProgramType PType>
591 j.at(
"Tree").get_to(p.
Tree);
holds variable type data.
#define HANDLE_ERROR_THROW(err)
< nsga2 selection operator for getting the front
auto Isnt(DataType dt) -> bool
Eigen::Array< bool, Eigen::Dynamic, 1 > ArrayXb
auto IsWeighable() noexcept -> bool
void from_json(const json &j, Fitness &f)
auto Is(NodeType nt) -> bool
tree< Node >::pre_order_iterator Iter
tree< Node >::post_order_iterator PostIter
void to_json(json &j, const Fitness &f)
Eigen::Array< int, Eigen::Dynamic, 1 > ArrayXi
An individual program, a.k.a. model.
Program(const std::reference_wrapper< SearchSpace > s, const tree< Node > t)
TreeType predict_proba(const Dataset &d)
void update_weights(const Dataset &d)
Updates the program's weights using non-linear least squares.
typename std::conditional_t< PType==PT::Regressor, ArrayXf, std::conditional_t< PType==PT::BinaryClassifier, ArrayXb, std::conditional_t< PType==PT::MulticlassClassifier, ArrayXi, std::conditional_t< PType==PT::Representer, ArrayXXf, ArrayXf > > > > RetType
the return type of the tree when calling :func:predict.
std::optional< std::reference_wrapper< SearchSpace > > SSref
int linear_complexity() const
count the linear complexity of the program.
RetType predict(const Ref< const ArrayXXf > &X)
Convenience function to call predict directly from X data.
void set_weights(const ArrayXf &weights)
Set the weights in the tree from an array of weights.
TreeType predict(const Dataset &d)
the standard predict function. Returns the output of the Tree directly.
static constexpr PT program_type
R predict_with_weights(const Dataset &d, const W **weights)
std::conditional_t< PType==PT::BinaryClassifier, ArrayXf, std::conditional_t< PType==PT::MulticlassClassifier, ArrayXXf, RetType > > TreeType
the type of output from the tree object
int complexity() const
count the (recursive) complexity of the program.
int size_at(Iter &top, bool include_weight=true) const
count the size of a given subtree, optionally including the weights in weighted nodes....
ArrayXf get_weights()
Get the weights of the tree as an array.
Program< PType > & fit(const Dataset &d)
int depth() const
count the tree depth of the program. The depth is not influenced by weighted nodes.
auto predict_with_weights(const Dataset &d, const ArrayXf &weights)
int get_n_weights() const
returns the number of weights in the program.
int depth_at(Iter &top) const
count the depth of a given subtree. The depth is not influenced by weighted nodes....
void unlock_nodes(int start_depth=0)
Iterates over the program, unlocking the nodes until it reaches a certain depth. It does not protect ...
vector< Node > linearize() const
turns program tree into a linear program.
ArrayXi predict(const Dataset &d)
Specialized predict function for multiclass classification.
void set_search_space(const std::reference_wrapper< SearchSpace > s)
ArrayXb predict(const Dataset &d)
Specialized predict function for binary classification.
string get_dot_model(string extras="") const
Get the model as a dot object.
string get_model(string fmt="compact", bool pretty=false) const
Get the model as a string.
void lock_nodes(int end_depth=0, bool skip_leaves=true)
Iterates over the program, locking the nodes until it reaches a certain depth.
TreeType predict_proba(const Ref< const ArrayXXf > &X)
Predict probabilities from X.
int depth_to_reach(Iter &top) const
count the depth until reaching the given subtree. The depth is not influenced by weighted nodes....
Program< PType > & fit(const Ref< const ArrayXXf > &X, const Ref< const ArrayXf > &y)
Convenience function to call fit directly from X,y data.
int size(bool include_weight=true) const
count the tree size of the program, including the weights in weighted nodes.
Holds a search space, consisting of operations and terminals and functions, and methods to sample tha...