14 BoostA2DE::BoostA2DE(
bool predict_voting) : Boost(predict_voting)
17 std::vector<int> BoostA2DE::initializeModels(
const Smoothing_t smoothing)
19 torch::Tensor weights_ = torch::full({ m }, 1.0 / m, torch::kFloat64);
20 std::vector<int> featuresSelected = featureSelection(weights_);
21 if (featuresSelected.size() < 2) {
22 notes.push_back(
"No features selected in initialization");
24 return std::vector<int>();
26 for (
int i = 0; i < featuresSelected.size() - 1; i++) {
27 for (
int j = i + 1; j < featuresSelected.size(); j++) {
28 auto parents = { featuresSelected[i], featuresSelected[j] };
29 std::unique_ptr<Classifier> model = std::make_unique<SPnDE>(parents);
30 model->fit(dataset, features, className, states, weights_, smoothing);
31 models.push_back(std::move(model));
32 significanceModels.push_back(1.0);
36 notes.push_back(
"Used features in initialization: " + std::to_string(featuresSelected.size()) +
" of " + std::to_string(features.size()) +
" with " + select_features_algorithm);
37 return featuresSelected;
39 void BoostA2DE::trainModel(
const torch::Tensor& weights,
const Smoothing_t smoothing)
52 torch::Tensor weights_ = torch::full({ m }, 1.0 / m, torch::kFloat64);
53 bool finished =
false;
54 std::vector<int> featuresUsed;
56 featuresUsed = initializeModels(smoothing);
57 if (featuresUsed.size() == 0) {
60 auto ypred = predict(X_train);
61 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
63 for (
int i = 0; i < n_models; ++i) {
64 significanceModels[i] = alpha_t;
72 double priorAccuracy = 0.0;
73 double improvement = 1.0;
74 double convergence_threshold = 1e-4;
80 bool ascending = order_algorithm == Orders.ASC;
81 std::mt19937 g{ 173 };
82 std::vector<std::pair<int, int>> pairSelection;
85 pairSelection = metrics.SelectKPairs(weights_, featuresUsed, ascending, 0);
86 if (order_algorithm == Orders.RAND) {
87 std::shuffle(pairSelection.begin(), pairSelection.end(), g);
89 int k = bisection ? pow(2, tolerance) : 1;
92 while (counter++ < k && pairSelection.size() > 0) {
93 auto feature_pair = pairSelection[0];
94 pairSelection.erase(pairSelection.begin());
95 std::unique_ptr<Classifier> model;
96 model = std::make_unique<SPnDE>(std::vector<int>({ feature_pair.first, feature_pair.second }));
97 model->fit(dataset, features, className, states, weights_, smoothing);
100 auto ypred = model->predict(X_train);
102 std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
106 models.push_back(std::move(model));
107 significanceModels.push_back(alpha_t);
112 std::tie(weights_, alpha_t, finished) = update_weights_block(k, y_train, weights_);
114 if (convergence && !finished) {
115 auto y_val_predict = predict(X_test);
116 double accuracy = (y_val_predict == y_test).sum().item<
double>() / (
double)y_test.size(0);
117 if (priorAccuracy == 0) {
118 priorAccuracy = accuracy;
120 improvement = accuracy - priorAccuracy;
122 if (improvement < convergence_threshold) {
130 if (convergence_best) {
132 priorAccuracy = std::max(accuracy, priorAccuracy);
135 priorAccuracy = accuracy;
139 finished = finished || tolerance > maxTolerance || pairSelection.size() == 0;
141 if (tolerance > maxTolerance) {
142 if (numItemsPack < n_models) {
143 notes.push_back(
"Convergence threshold reached & " + std::to_string(numItemsPack) +
" models eliminated");
145 for (
int i = 0; i < numItemsPack; ++i) {
146 significanceModels.pop_back();
151 notes.push_back(
"Convergence threshold reached & 0 models eliminated");
155 if (pairSelection.size() > 0) {
156 notes.push_back(
"Pairs not used in train: " + std::to_string(pairSelection.size()));
159 notes.push_back(
"Number of models: " + std::to_string(n_models));
161 std::vector<std::string> BoostA2DE::graph(
const std::string& title)
const
163 return Ensemble::graph(title);