7#include "bayesnet/classifiers/XSPODE.h"
8#include "bayesnet/utils/TensorUtils.h"
15 XBAODE::XBAODE() : Boost(false) {}
16 std::vector<int> XBAODE::initializeModels(
const Smoothing_t smoothing)
18 torch::Tensor weights_ = torch::full({m}, 1.0 / m, torch::kFloat64);
19 std::vector<int> featuresSelected = featureSelection(weights_);
20 for (
const int &feature : featuresSelected)
22 std::unique_ptr<Classifier> model = std::make_unique<XSpode>(feature);
23 model->fit(dataset, features, className, states, weights_, smoothing);
24 add_model(std::move(model), 1.0);
26 notes.push_back(
"Used features in initialization: " + std::to_string(featuresSelected.size()) +
" of " +
27 std::to_string(features.size()) +
" with " + select_features_algorithm);
28 return featuresSelected;
30 void XBAODE::trainModel(
const torch::Tensor &weights,
const bayesnet::Smoothing_t smoothing)
32 X_train_ = TensorUtils::to_matrix(X_train);
33 y_train_ = TensorUtils::to_vector<int>(y_train);
36 X_test_ = TensorUtils::to_matrix(X_test);
37 y_test_ = TensorUtils::to_vector<int>(y_test);
41 torch::Tensor weights_ = torch::full({m}, 1.0 / m, torch::kFloat64);
42 bool finished =
false;
43 std::vector<int> featuresUsed;
47 featuresUsed = initializeModels(smoothing);
48 auto ypred = predict(X_train_);
49 auto ypred_t = torch::tensor(ypred);
50 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred_t, weights_);
52 for (
const int &feature : featuresUsed)
54 significanceModels.pop_back();
56 for (
const int &feature : featuresUsed)
58 significanceModels.push_back(alpha_t);
69 double priorAccuracy = 0.0;
70 double improvement = 1.0;
71 double convergence_threshold = 1e-4;
77 bool ascending = order_algorithm == bayesnet::Orders.ASC;
82 auto featureSelection = metrics.SelectKBestWeighted(weights_, ascending, n);
83 if (order_algorithm == bayesnet::Orders.RAND)
85 std::shuffle(featureSelection.begin(), featureSelection.end(), g);
88 featureSelection.erase(remove_if(featureSelection.begin(), featureSelection.end(),
91 return std::find(featuresUsed.begin(), featuresUsed.end(), x) !=
94 featureSelection.end());
95 int k = bisection ? pow(2, tolerance) : 1;
99 while (counter++ < k && featureSelection.size() > 0)
101 auto feature = featureSelection[0];
102 featureSelection.erase(featureSelection.begin());
103 std::unique_ptr<Classifier> model;
104 model = std::make_unique<XSpode>(feature);
105 model->fit(dataset, features, className, states, weights_, smoothing);
112 std::vector<int> ypred;
119 add_model(std::move(model), 1.0);
121 ypred = predict(X_train_);
122 model = std::move(models.back());
128 ypred = model->predict(X_train_);
131 auto ypred_t = torch::tensor(ypred);
132 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred_t, weights_);
135 featuresUsed.push_back(feature);
136 add_model(std::move(model), alpha_t);
141 if (convergence && !finished)
143 auto y_val_predict = predict(X_test);
144 double accuracy = (y_val_predict == y_test).sum().item<
double>() / (
double)y_test.size(0);
145 if (priorAccuracy == 0)
147 priorAccuracy = accuracy;
151 improvement = accuracy - priorAccuracy;
153 if (improvement < convergence_threshold)
168 if (convergence_best)
171 priorAccuracy = std::max(accuracy, priorAccuracy);
176 priorAccuracy = accuracy;
181 finished = finished || tolerance > maxTolerance || featuresUsed.size() == features.size();
183 if (tolerance > maxTolerance)
185 if (numItemsPack < n_models)
187 notes.push_back(
"Convergence threshold reached & " + std::to_string(numItemsPack) +
" models eliminated");
190 for (
int i = featuresUsed.size() - 1; i >= featuresUsed.size() - numItemsPack; --i)
199 notes.push_back(
"Convergence threshold reached & 0 models eliminated");
204 if (featuresUsed.size() != features.size())
206 notes.push_back(
"Used features in train: " + std::to_string(featuresUsed.size()) +
" of " +
207 std::to_string(features.size()));
208 status = bayesnet::WARNING;
210 notes.push_back(
"Number of models: " + std::to_string(n_models));