Add XBAODE & XSPODE from bayesnet
This commit is contained in:
@@ -27,7 +27,6 @@ add_executable(
|
||||
reports/ReportExcel.cpp reports/ReportBase.cpp reports/ExcelFile.cpp
|
||||
results/Result.cpp
|
||||
experimental_clfs/XA1DE.cpp
|
||||
experimental_clfs/XBAODE.cpp
|
||||
experimental_clfs/ExpClf.cpp
|
||||
)
|
||||
target_link_libraries(b_best Boost::boost "${PyClassifiers}" "${BayesNet}" fimdlp ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::python Boost::numpy "${XLSXWRITER_LIB}")
|
||||
@@ -41,7 +40,6 @@ add_executable(b_grid commands/b_grid.cpp ${grid_sources}
|
||||
reports/ReportConsole.cpp reports/ReportBase.cpp
|
||||
results/Result.cpp
|
||||
experimental_clfs/XA1DE.cpp
|
||||
experimental_clfs/XBAODE.cpp
|
||||
experimental_clfs/ExpClf.cpp
|
||||
)
|
||||
target_link_libraries(b_grid ${MPI_CXX_LIBRARIES} "${PyClassifiers}" "${BayesNet}" fimdlp ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::python Boost::numpy)
|
||||
@@ -53,7 +51,6 @@ add_executable(b_list commands/b_list.cpp
|
||||
reports/ReportExcel.cpp reports/ExcelFile.cpp reports/ReportBase.cpp reports/DatasetsExcel.cpp reports/DatasetsConsole.cpp reports/ReportsPaged.cpp
|
||||
results/Result.cpp results/ResultsDatasetExcel.cpp results/ResultsDataset.cpp results/ResultsDatasetConsole.cpp
|
||||
experimental_clfs/XA1DE.cpp
|
||||
experimental_clfs/XBAODE.cpp
|
||||
experimental_clfs/ExpClf.cpp
|
||||
)
|
||||
target_link_libraries(b_list "${PyClassifiers}" "${BayesNet}" fimdlp ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::python Boost::numpy "${XLSXWRITER_LIB}")
|
||||
@@ -66,7 +63,6 @@ add_executable(b_main commands/b_main.cpp ${main_sources}
|
||||
reports/ReportConsole.cpp reports/ReportBase.cpp
|
||||
results/Result.cpp
|
||||
experimental_clfs/XA1DE.cpp
|
||||
experimental_clfs/XBAODE.cpp
|
||||
experimental_clfs/ExpClf.cpp
|
||||
)
|
||||
target_link_libraries(b_main "${PyClassifiers}" "${BayesNet}" fimdlp ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::python Boost::numpy)
|
||||
|
158
src/experimental_clfs/ExpEnsemble.cpp
Normal file
158
src/experimental_clfs/ExpEnsemble.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
// ***************************************************************
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Ricardo Montañana Gómez
|
||||
// SPDX-FileType: SOURCE
|
||||
// SPDX-License-Identifier: MIT
|
||||
// ***************************************************************
|
||||
|
||||
#include "ExpEnsemble.h"
|
||||
#include "TensorUtils.hpp"
|
||||
|
||||
namespace platform {
|
||||
ExpEnsemble::ExpEnsemble() : semaphore_{ CountingSemaphore::getInstance() }, Boost(false)
|
||||
{
|
||||
validHyperparameters = {};
|
||||
}
|
||||
//
|
||||
// Parents
|
||||
//
|
||||
void ExpEnsemble::add_model(std::unique_ptr<XSpode> model)
|
||||
{
|
||||
models.push_back(std::move(model));
|
||||
n_models++;
|
||||
}
|
||||
void ExpEnsemble::remove_last_model()
|
||||
{
|
||||
models.pop_back();
|
||||
n_models--;
|
||||
}
|
||||
//
|
||||
// Predict
|
||||
//
|
||||
torch::Tensor ExpEnsemble::predict(torch::Tensor& X)
|
||||
{
|
||||
auto X_ = TensorUtils::to_matrix(X);
|
||||
torch::Tensor y = torch::tensor(predict(X_));
|
||||
return y;
|
||||
}
|
||||
torch::Tensor ExpEnsemble::predict_proba(torch::Tensor& X)
|
||||
{
|
||||
auto X_ = TensorUtils::to_matrix(X);
|
||||
auto probabilities = predict_proba(X_);
|
||||
auto n_samples = X.size(1);
|
||||
int n_classes = probabilities[0].size();
|
||||
auto y = torch::zeros({ n_samples, n_classes });
|
||||
for (int i = 0; i < n_samples; i++) {
|
||||
for (int j = 0; j < n_classes; j++) {
|
||||
y[i][j] = probabilities[i][j];
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
float ExpEnsemble::score(torch::Tensor& X, torch::Tensor& y)
|
||||
{
|
||||
auto X_ = TensorUtils::to_matrix(X);
|
||||
auto y_ = TensorUtils::to_vector<int>(y);
|
||||
return score(X_, y_);
|
||||
}
|
||||
std::vector<std::vector<double>> ExpEnsemble::predict_proba(const std::vector<std::vector<int>>& test_data)
|
||||
{
|
||||
int test_size = test_data[0].size();
|
||||
int sample_size = test_data.size();
|
||||
auto probabilities = std::vector<std::vector<double>>(test_size, std::vector<double>(getClassNumStates()));
|
||||
int chunk_size = std::min(150, int(test_size / semaphore_.getMaxCount()) + 1);
|
||||
std::vector<std::thread> threads;
|
||||
auto worker = [&](const std::vector<std::vector<int>>& samples, int begin, int chunk, int sample_size, std::vector<std::vector<double>>& predictions) {
|
||||
std::string threadName = "(V)PWorker-" + std::to_string(begin) + "-" + std::to_string(chunk);
|
||||
#if defined(__linux__)
|
||||
pthread_setname_np(pthread_self(), threadName.c_str());
|
||||
#else
|
||||
pthread_setname_np(threadName.c_str());
|
||||
#endif
|
||||
|
||||
std::vector<int> instance(sample_size);
|
||||
for (int sample = begin; sample < begin + chunk; ++sample) {
|
||||
for (int feature = 0; feature < sample_size; ++feature) {
|
||||
instance[feature] = samples[feature][sample];
|
||||
}
|
||||
// predictions[sample] = aode_.predict_proba(instance);
|
||||
}
|
||||
semaphore_.release();
|
||||
};
|
||||
for (int begin = 0; begin < test_size; begin += chunk_size) {
|
||||
int chunk = std::min(chunk_size, test_size - begin);
|
||||
semaphore_.acquire();
|
||||
threads.emplace_back(worker, test_data, begin, chunk, sample_size, std::ref(probabilities));
|
||||
}
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
return probabilities;
|
||||
}
|
||||
std::vector<int> ExpEnsemble::predict(std::vector<std::vector<int>>& test_data)
|
||||
{
|
||||
if (!fitted) {
|
||||
throw std::logic_error(CLASSIFIER_NOT_FITTED);
|
||||
}
|
||||
auto probabilities = predict_proba(test_data);
|
||||
std::vector<int> predictions(probabilities.size(), 0);
|
||||
|
||||
for (size_t i = 0; i < probabilities.size(); i++) {
|
||||
predictions[i] = std::distance(probabilities[i].begin(), std::max_element(probabilities[i].begin(), probabilities[i].end()));
|
||||
}
|
||||
|
||||
return predictions;
|
||||
}
|
||||
float ExpEnsemble::score(std::vector<std::vector<int>>& test_data, std::vector<int>& labels)
|
||||
{
|
||||
Timer timer;
|
||||
timer.start();
|
||||
std::vector<int> predictions = predict(test_data);
|
||||
int correct = 0;
|
||||
|
||||
for (size_t i = 0; i < predictions.size(); i++) {
|
||||
if (predictions[i] == labels[i]) {
|
||||
correct++;
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
std::cout << "* Time to predict: " << timer.getDurationString() << std::endl;
|
||||
}
|
||||
return static_cast<float>(correct) / predictions.size();
|
||||
}
|
||||
|
||||
//
|
||||
// statistics
|
||||
//
|
||||
int ExpEnsemble::getNumberOfNodes() const
|
||||
{
|
||||
if (models_.empty()) {
|
||||
return 0;
|
||||
}
|
||||
return n_models * (models_.at(0)->getNFeatures() + 1);
|
||||
}
|
||||
int ExpEnsemble::getNumberOfEdges() const
|
||||
{
|
||||
if (models_.empty()) {
|
||||
return 0;
|
||||
}
|
||||
return n_models * (2 * models_.at(0)->getNFeatures() - 1);
|
||||
}
|
||||
int ExpEnsemble::getNumberOfStates() const
|
||||
{
|
||||
if (models_.empty()) {
|
||||
return 0;
|
||||
}
|
||||
auto states = models_.at(0)->getStates();
|
||||
int nFeatures = models_.at(0)->getNFeatures();
|
||||
return std::accumulate(states.begin(), states.end(), 0) * nFeatures * n_models;
|
||||
}
|
||||
int ExpEnsemble::getClassNumStates() const
|
||||
{
|
||||
if (models_.empty()) {
|
||||
return 0;
|
||||
}
|
||||
return models_.at(0)->statesClass();
|
||||
}
|
||||
|
||||
|
||||
}
|
66
src/experimental_clfs/ExpEnsemble.h
Normal file
66
src/experimental_clfs/ExpEnsemble.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// ***************************************************************
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Ricardo Montañana Gómez
|
||||
// SPDX-FileType: SOURCE
|
||||
// SPDX-License-Identifier: MIT
|
||||
// ***************************************************************
|
||||
|
||||
#ifndef EXPENSEMBLE_H
|
||||
#define EXPENSEMBLE_H
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <bayesnet/ensembles/Boost.h>
|
||||
#include <bayesnet/network/Smoothing.h>
|
||||
#include "common/Timer.hpp"
|
||||
#include "CountingSemaphore.hpp"
|
||||
#include "XSpode.hpp"
|
||||
|
||||
namespace platform {
|
||||
class ExpEnsemble : public bayesnet::Boost {
|
||||
public:
|
||||
ExpEnsemble();
|
||||
virtual ~ExpEnsemble() = default;
|
||||
std::vector<int> predict(std::vector<std::vector<int>>& X) override;
|
||||
torch::Tensor predict(torch::Tensor& X) override;
|
||||
torch::Tensor predict_proba(torch::Tensor& X) override;
|
||||
std::vector<int> predict_spode(std::vector<std::vector<int>>& test_data, int parent);
|
||||
std::vector<std::vector<double>> predict_proba(const std::vector<std::vector<int>>& X);
|
||||
float score(std::vector<std::vector<int>>& X, std::vector<int>& y) override;
|
||||
float score(torch::Tensor& X, torch::Tensor& y) override;
|
||||
int getNumberOfNodes() const override;
|
||||
int getNumberOfEdges() const override;
|
||||
int getNumberOfStates() const override;
|
||||
int getClassNumStates() const override;
|
||||
std::vector<std::string> show() const override { return {}; }
|
||||
std::vector<std::string> topological_order() override { return {}; }
|
||||
std::string dump_cpt() const override { return ""; }
|
||||
void setDebug(bool debug) { this->debug = debug; }
|
||||
bayesnet::status_t getStatus() const override { return status; }
|
||||
std::vector<std::string> getNotes() const override { return notes; }
|
||||
std::vector<std::string> graph(const std::string& title = "") const override { return {}; }
|
||||
protected:
|
||||
void add_model(std::unique_ptr<XSpode> model);
|
||||
void remove_last_model();
|
||||
bool debug = false;
|
||||
std::vector <std::unique_ptr<XSpode>> models_;
|
||||
torch::Tensor weights_;
|
||||
std::vector<double> significanceModels_;
|
||||
const std::string CLASSIFIER_NOT_FITTED = "Classifier has not been fitted";
|
||||
inline void normalize_weights(int num_instances)
|
||||
{
|
||||
double sum = weights_.sum().item<double>();
|
||||
if (sum == 0) {
|
||||
weights_ = torch::full({ num_instances }, 1.0);
|
||||
} else {
|
||||
for (int i = 0; i < weights_.size(0); ++i) {
|
||||
weights_[i] = weights_[i].item<double>() * num_instances / sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
CountingSemaphore& semaphore_;
|
||||
};
|
||||
}
|
||||
#endif // EXPENSEMBLE_H
|
@@ -19,6 +19,16 @@ namespace platform {
|
||||
validHyperparameters = { "alpha_block", "order", "convergence", "convergence_best", "bisection", "threshold", "maxTolerance",
|
||||
"predict_voting", "select_features" };
|
||||
}
|
||||
void XBAODE::add_model(std::unique_ptr<XSpode> model)
|
||||
{
|
||||
models.push_back(std::move(model));
|
||||
n_models++;
|
||||
}
|
||||
void XBAODE::remove_last_model()
|
||||
{
|
||||
models.pop_back();
|
||||
n_models--;
|
||||
}
|
||||
void XBAODE::trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing)
|
||||
{
|
||||
fitted = true;
|
||||
@@ -30,30 +40,36 @@ namespace platform {
|
||||
//
|
||||
// Logging setup
|
||||
//
|
||||
loguru::set_thread_name("XBAODE");
|
||||
loguru::g_stderr_verbosity = loguru::Verbosity_OFF;
|
||||
loguru::add_file("XBAODE.log", loguru::Truncate, loguru::Verbosity_MAX);
|
||||
// loguru::set_thread_name("XBAODE");
|
||||
// loguru::g_stderr_verbosity = loguru::Verbosity_OFF;
|
||||
// loguru::add_file("XBAODE.log", loguru::Truncate, loguru::Verbosity_MAX);
|
||||
|
||||
// Algorithm based on the adaboost algorithm for classification
|
||||
// as explained in Ensemble methods (Zhi-Hua Zhou, 2012)
|
||||
double alpha_t = 0;
|
||||
weights_ = torch::full({ m }, 1.0 / static_cast<double>(m), torch::kFloat64);
|
||||
weights_ = torch::full({ m }, 1.0 / static_cast<double>(m), torch::kFloat64); // m initialized in Classifier.cc
|
||||
significanceModels.resize(n, 0.0); // n initialized in Classifier.cc
|
||||
bool finished = false;
|
||||
std::vector<int> featuresUsed;
|
||||
aode_.fit(X_train_, y_train_, features, className, states, weights_, false);
|
||||
n_models = 0;
|
||||
std::unique_ptr<XSpode> model;
|
||||
if (selectFeatures) {
|
||||
featuresUsed = featureSelection(weights_);
|
||||
add_active_parents(featuresUsed);
|
||||
for (const auto& parent : featuresUsed) {
|
||||
model = std::unique_ptr<XSpode>(new XSpode(parent));
|
||||
model->fit(X_train_, y_train_, weights_, smoothing);
|
||||
std::cout << model->getNFeatures() << std::endl;
|
||||
add_model(std::move(model));
|
||||
}
|
||||
notes.push_back("Used features in initialization: " + std::to_string(featuresUsed.size()) + " of " + std::to_string(features.size()) + " with " + select_features_algorithm);
|
||||
auto ypred = ExpClf::predict(X_train);
|
||||
auto ypred = ExpEnsemble::predict(X_train);
|
||||
std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
|
||||
// Update significance of the models
|
||||
for (const auto& parent : featuresUsed) {
|
||||
aode_.significance_models_[parent] = alpha_t;
|
||||
significanceModels_[parent] = alpha_t;
|
||||
}
|
||||
n_models = featuresUsed.size();
|
||||
VLOG_SCOPE_F(1, "SelectFeatures. alpha_t: %f n_models: %d", alpha_t, n_models);
|
||||
// VLOG_SCOPE_F(1, "SelectFeatures. alpha_t: %f n_models: %d", alpha_t, n_models);
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
@@ -83,29 +99,28 @@ namespace platform {
|
||||
);
|
||||
int k = bisection ? pow(2, tolerance) : 1;
|
||||
int counter = 0; // The model counter of the current pack
|
||||
VLOG_SCOPE_F(1, "counter=%d k=%d featureSelection.size: %zu", counter, k, featureSelection.size());
|
||||
// VLOG_SCOPE_F(1, "counter=%d k=%d featureSelection.size: %zu", counter, k, featureSelection.size());
|
||||
while (counter++ < k && featureSelection.size() > 0) {
|
||||
auto feature = featureSelection[0];
|
||||
featureSelection.erase(featureSelection.begin());
|
||||
auto model = XSpode(feature);
|
||||
model.fit(X_train_, y_train_, weights_, smoothing);
|
||||
model = std::unique_ptr<XSpode>(new XSpode(feature));
|
||||
model->fit(X_train_, y_train_, weights_, smoothing);
|
||||
std::vector<int> ypred;
|
||||
if (alpha_block) {
|
||||
//
|
||||
// Compute the prediction with the current ensemble + model
|
||||
//
|
||||
// Add the model to the ensemble
|
||||
n_models++;
|
||||
aode_.significance_models_[feature] = 1.0;
|
||||
aode_.add_active_parent(feature);
|
||||
significanceModels[feature] = 1.0;
|
||||
add_model(std::move(model));
|
||||
// Compute the prediction
|
||||
ypred = ExpClf::predict(X_train_);
|
||||
ypred = ExpEnsemble::predict(X_train_);
|
||||
// Remove the model from the ensemble
|
||||
aode_.significance_models_[feature] = 0.0;
|
||||
aode_.remove_last_parent();
|
||||
n_models--;
|
||||
significanceModels[feature] = 0.0;
|
||||
model = std::move(models_.back());
|
||||
remove_last_model();
|
||||
} else {
|
||||
ypred = model.predict(X_train_);
|
||||
ypred = model->predict(X_train_);
|
||||
}
|
||||
// Step 3.1: Compute the classifier amout of say
|
||||
auto ypred_t = torch::tensor(ypred);
|
||||
@@ -113,13 +128,12 @@ namespace platform {
|
||||
// Step 3.4: Store classifier and its accuracy to weigh its future vote
|
||||
numItemsPack++;
|
||||
featuresUsed.push_back(feature);
|
||||
aode_.add_active_parent(feature);
|
||||
aode_.significance_models_[feature] = alpha_t;
|
||||
n_models++;
|
||||
VLOG_SCOPE_F(2, "finished: %d numItemsPack: %d n_models: %d featuresUsed: %zu", finished, numItemsPack, n_models, featuresUsed.size());
|
||||
add_model(std::move(model));
|
||||
significanceModels[feature] = alpha_t;
|
||||
// VLOG_SCOPE_F(2, "finished: %d numItemsPack: %d n_models: %d featuresUsed: %zu", finished, numItemsPack, n_models, featuresUsed.size());
|
||||
} // End of the pack
|
||||
if (convergence && !finished) {
|
||||
auto y_val_predict = ExpClf::predict(X_test);
|
||||
auto y_val_predict = ExpEnsemble::predict(X_test);
|
||||
double accuracy = (y_val_predict == y_test).sum().item<double>() / (double)y_test.size(0);
|
||||
if (priorAccuracy == 0) {
|
||||
priorAccuracy = accuracy;
|
||||
@@ -127,10 +141,10 @@ namespace platform {
|
||||
improvement = accuracy - priorAccuracy;
|
||||
}
|
||||
if (improvement < convergence_threshold) {
|
||||
VLOG_SCOPE_F(3, " (improvement<threshold) tolerance: %d numItemsPack: %d improvement: %f prior: %f current: %f", tolerance, numItemsPack, improvement, priorAccuracy, accuracy);
|
||||
// VLOG_SCOPE_F(3, " (improvement<threshold) tolerance: %d numItemsPack: %d improvement: %f prior: %f current: %f", tolerance, numItemsPack, improvement, priorAccuracy, accuracy);
|
||||
tolerance++;
|
||||
} else {
|
||||
VLOG_SCOPE_F(3, "* (improvement>=threshold) Reset. tolerance: %d numItemsPack: %d improvement: %f prior: %f current: %f", tolerance, numItemsPack, improvement, priorAccuracy, accuracy);
|
||||
// VLOG_SCOPE_F(3, "* (improvement>=threshold) Reset. tolerance: %d numItemsPack: %d improvement: %f prior: %f current: %f", tolerance, numItemsPack, improvement, priorAccuracy, accuracy);
|
||||
tolerance = 0; // Reset the counter if the model performs better
|
||||
numItemsPack = 0;
|
||||
}
|
||||
@@ -142,22 +156,21 @@ namespace platform {
|
||||
priorAccuracy = accuracy;
|
||||
}
|
||||
}
|
||||
VLOG_SCOPE_F(1, "tolerance: %d featuresUsed.size: %zu features.size: %zu", tolerance, featuresUsed.size(), features.size());
|
||||
// VLOG_SCOPE_F(1, "tolerance: %d featuresUsed.size: %zu features.size: %zu", tolerance, featuresUsed.size(), features.size());
|
||||
finished = finished || tolerance > maxTolerance || featuresUsed.size() == features.size();
|
||||
}
|
||||
if (tolerance > maxTolerance) {
|
||||
if (numItemsPack < n_models) {
|
||||
notes.push_back("Convergence threshold reached & " + std::to_string(numItemsPack) + " models eliminated");
|
||||
VLOG_SCOPE_F(4, "Convergence threshold reached & %d models eliminated of %d", numItemsPack, n_models);
|
||||
// VLOG_SCOPE_F(4, "Convergence threshold reached & %d models eliminated of %d", numItemsPack, n_models);
|
||||
for (int i = featuresUsed.size() - 1; i >= featuresUsed.size() - numItemsPack; --i) {
|
||||
aode_.remove_last_parent();
|
||||
aode_.significance_models_[featuresUsed[i]] = 0.0;
|
||||
n_models--;
|
||||
remove_last_model();
|
||||
significanceModels[featuresUsed[i]] = 0.0;
|
||||
}
|
||||
VLOG_SCOPE_F(4, "*Convergence threshold %d models left & %d features used.", n_models, featuresUsed.size());
|
||||
// VLOG_SCOPE_F(4, "*Convergence threshold %d models left & %d features used.", n_models, featuresUsed.size());
|
||||
} else {
|
||||
notes.push_back("Convergence threshold reached & 0 models eliminated");
|
||||
VLOG_SCOPE_F(4, "Convergence threshold reached & 0 models eliminated n_models=%d numItemsPack=%d", n_models, numItemsPack);
|
||||
// VLOG_SCOPE_F(4, "Convergence threshold reached & 0 models eliminated n_models=%d numItemsPack=%d", n_models, numItemsPack);
|
||||
}
|
||||
}
|
||||
if (featuresUsed.size() != features.size()) {
|
||||
|
@@ -12,10 +12,10 @@
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "common/Timer.hpp"
|
||||
#include "ExpClf.h"
|
||||
#include "ExpEnsemble.h"
|
||||
|
||||
namespace platform {
|
||||
class XBAODE {
|
||||
class XBAODE : public Boost {
|
||||
|
||||
// Hay que hacer un vector de modelos entrenados y hacer un predict ensemble con todos ellos
|
||||
// Probar XA1DE con smooth original y laplace y comprobar diferencias si se pasan pesos a 1 o a 1/m
|
||||
@@ -25,10 +25,10 @@ namespace platform {
|
||||
protected:
|
||||
void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override;
|
||||
private:
|
||||
void add_model(std::unique_ptr<XSpode> model);
|
||||
void remove_last_model();
|
||||
std::vector<std::vector<int>> X_train_, X_test_;
|
||||
std::vector<int> y_train_, y_test_;
|
||||
torch::Tensor dataset;
|
||||
int n_models;
|
||||
std::string version = "0.9.7";
|
||||
};
|
||||
}
|
||||
|
@@ -11,24 +11,29 @@
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <torch/torch.h>
|
||||
#include <bayesnet/network/Smoothing.h>
|
||||
#include <bayesnet/classifiers/Classifier.h>
|
||||
#include "CountingSemaphore.hpp"
|
||||
|
||||
|
||||
namespace platform {
|
||||
|
||||
class XSpode {
|
||||
class XSpode : public bayesnet::Classifier {
|
||||
public:
|
||||
// --------------------------------------
|
||||
// Constructor
|
||||
//
|
||||
// Supply which feature index is the single super-parent (“spIndex”).
|
||||
// --------------------------------------
|
||||
XSpode(int spIndex)
|
||||
explicit XSpode(int spIndex)
|
||||
: superParent_{ spIndex },
|
||||
nFeatures_{ 0 },
|
||||
statesClass_{ 0 },
|
||||
fitted_{ false },
|
||||
alpha_{ 1.0 },
|
||||
semaphore_{ CountingSemaphore::getInstance() }
|
||||
initializer_{ 1.0 },
|
||||
semaphore_{ CountingSemaphore::getInstance() } : bayesnet::Classifier(bayesnet::Network())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -380,6 +385,17 @@ namespace platform {
|
||||
oss << "---------------------\n";
|
||||
return oss.str();
|
||||
}
|
||||
int statesClass() const { return statesClass_; }
|
||||
int getNFeatures() const { return nFeatures_; }
|
||||
int getNumberOfStates() const
|
||||
{
|
||||
return std::accumulate(states_.begin(), states_.end(), 0) * nFeatures_;
|
||||
}
|
||||
int getNumberOfEdges() const
|
||||
{
|
||||
return nFeatures_ * (2 * nFeatures_ - 1);
|
||||
}
|
||||
std::vector<int>& getStates() { return states_; }
|
||||
|
||||
private:
|
||||
// --------------------------------------
|
||||
|
@@ -5,11 +5,13 @@
|
||||
#include <bayesnet/ensembles/AODE.h>
|
||||
#include <bayesnet/ensembles/A2DE.h>
|
||||
#include <bayesnet/ensembles/AODELd.h>
|
||||
#include <bayesnet/ensembles/XBAODE.h>
|
||||
#include <bayesnet/ensembles/BoostAODE.h>
|
||||
#include <bayesnet/ensembles/BoostA2DE.h>
|
||||
#include <bayesnet/classifiers/TAN.h>
|
||||
#include <bayesnet/classifiers/KDB.h>
|
||||
#include <bayesnet/classifiers/SPODE.h>
|
||||
#include <bayesnet/classifiers/XSPODE.h>
|
||||
#include <bayesnet/classifiers/SPnDE.h>
|
||||
#include <bayesnet/classifiers/TANLd.h>
|
||||
#include <bayesnet/classifiers/KDBLd.h>
|
||||
@@ -21,7 +23,7 @@
|
||||
#include <pyclassifiers/XGBoost.h>
|
||||
#include <pyclassifiers/RandomForest.h>
|
||||
#include "../experimental_clfs/XA1DE.h"
|
||||
#include "../experimental_clfs/XBAODE.h"
|
||||
|
||||
namespace platform {
|
||||
class Models {
|
||||
public:
|
||||
|
@@ -35,9 +35,11 @@ namespace platform {
|
||||
[](void) -> bayesnet::BaseClassifier* { return new pywrap::RandomForest();});
|
||||
static Registrar registrarXGB("XGBoost",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new pywrap::XGBoost();});
|
||||
static Registrar registrarXA1DE("XA1DE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new XA1DE();});
|
||||
static Registrar registrarXSPODE("XSPODE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::XSpode(0);});
|
||||
static Registrar registrarXBAODE("XBAODE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new XBAODE();});
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::XBAODE();});
|
||||
static Registrar registrarXA1DE("XA1DE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new XA1DE();});
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user