12#include "bayesnet/feature_selection/CFS.h"
13#include "bayesnet/feature_selection/FCBF.h"
14#include "bayesnet/feature_selection/IWSS.h"
19 BoostA2DE::BoostA2DE(
bool predict_voting) : Boost(predict_voting)
22 std::vector<int> BoostA2DE::initializeModels()
24 torch::Tensor weights_ = torch::full({ m }, 1.0 / m, torch::kFloat64);
25 std::vector<int> featuresSelected = featureSelection(weights_);
26 if (featuresSelected.size() < 2) {
27 notes.push_back(
"No features selected in initialization");
29 return std::vector<int>();
31 for (
int i = 0; i < featuresSelected.size() - 1; i++) {
32 for (
int j = i + 1; j < featuresSelected.size(); j++) {
33 auto parents = { featuresSelected[i], featuresSelected[j] };
34 std::unique_ptr<Classifier> model = std::make_unique<SPnDE>(parents);
35 model->fit(dataset, features, className, states, weights_);
36 models.push_back(std::move(model));
37 significanceModels.push_back(1.0);
41 notes.push_back(
"Used features in initialization: " + std::to_string(featuresSelected.size()) +
" of " + std::to_string(features.size()) +
" with " + select_features_algorithm);
42 return featuresSelected;
44 void BoostA2DE::trainModel(
const torch::Tensor& weights)
57 torch::Tensor weights_ = torch::full({ m }, 1.0 / m, torch::kFloat64);
58 bool finished =
false;
59 std::vector<int> featuresUsed;
61 featuresUsed = initializeModels();
62 auto ypred = predict(X_train);
63 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
65 for (
int i = 0; i < n_models; ++i) {
66 significanceModels[i] = alpha_t;
74 double priorAccuracy = 0.0;
75 double improvement = 1.0;
76 double convergence_threshold = 1e-4;
82 bool ascending = order_algorithm == Orders.ASC;
83 std::mt19937 g{ 173 };
84 std::vector<std::pair<int, int>> pairSelection;
87 pairSelection = metrics.SelectKPairs(weights_, featuresUsed, ascending, 0);
88 if (order_algorithm == Orders.RAND) {
89 std::shuffle(pairSelection.begin(), pairSelection.end(), g);
91 int k = bisection ? pow(2, tolerance) : 1;
94 while (counter++ < k && pairSelection.size() > 0) {
95 auto feature_pair = pairSelection[0];
96 pairSelection.erase(pairSelection.begin());
97 std::unique_ptr<Classifier> model;
98 model = std::make_unique<SPnDE>(std::vector<int>({ feature_pair.first, feature_pair.second }));
99 model->fit(dataset, features, className, states, weights_);
102 auto ypred = model->predict(X_train);
104 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
108 models.push_back(std::move(model));
109 significanceModels.push_back(alpha_t);
114 std::tie(weights_, alpha_t, finished) = update_weights_block(k, y_train, weights_);
116 if (convergence && !finished) {
117 auto y_val_predict = predict(X_test);
118 double accuracy = (y_val_predict == y_test).sum().item<
double>() / (
double)y_test.size(0);
119 if (priorAccuracy == 0) {
120 priorAccuracy = accuracy;
122 improvement = accuracy - priorAccuracy;
124 if (improvement < convergence_threshold) {
132 if (convergence_best) {
134 priorAccuracy = std::max(accuracy, priorAccuracy);
137 priorAccuracy = accuracy;
141 finished = finished || tolerance > maxTolerance || pairSelection.size() == 0;
143 if (tolerance > maxTolerance) {
144 if (numItemsPack < n_models) {
145 notes.push_back(
"Convergence threshold reached & " + std::to_string(numItemsPack) +
" models eliminated");
147 for (
int i = 0; i < numItemsPack; ++i) {
148 significanceModels.pop_back();
153 notes.push_back(
"Convergence threshold reached & 0 models eliminated");
157 if (pairSelection.size() > 0) {
158 notes.push_back(
"Pairs not used in train: " + std::to_string(pairSelection.size()));
161 notes.push_back(
"Number of models: " + std::to_string(n_models));
163 std::vector<std::string> BoostA2DE::graph(
const std::string& title)
const
165 return Ensemble::graph(title);