Continue integration into trainModel
This commit is contained in:
4
Makefile
4
Makefile
@@ -98,8 +98,8 @@ test: ## Run tests (opt="-s") to verbose output the tests, (opt="-c='Test Maximu
|
|||||||
fname = iris
|
fname = iris
|
||||||
example: ## Build sample
|
example: ## Build sample
|
||||||
@echo ">>> Building Sample...";
|
@echo ">>> Building Sample...";
|
||||||
@cmake --build build_debug -t sample
|
@cmake --build $(f_release) -t sample
|
||||||
build_debug/sample/PlatformSample --model BoostAODE --dataset $(fname) --discretize --stratified
|
$(f_release)/sample/PlatformSample --model BoostAODE --dataset $(fname) --discretize --stratified
|
||||||
@echo ">>> Done";
|
@echo ">>> Done";
|
||||||
|
|
||||||
|
|
||||||
|
51
src/experimental_clfs/TensorUtils.hpp
Normal file
51
src/experimental_clfs/TensorUtils.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef TENSORUTILS_HPP
|
||||||
|
#define TENSORUTILS_HPP
|
||||||
|
#include <torch/torch.h>
|
||||||
|
#include <vector>
|
||||||
|
namespace platform {
|
||||||
|
class TensorUtils {
|
||||||
|
public:
|
||||||
|
static std::vector<std::vector<int>> to_matrix(const torch::Tensor& X)
|
||||||
|
{
|
||||||
|
// Ensure tensor is contiguous in memory
|
||||||
|
auto X_contig = X.contiguous();
|
||||||
|
|
||||||
|
// Access tensor data pointer directly
|
||||||
|
auto data_ptr = X_contig.data_ptr<int>();
|
||||||
|
|
||||||
|
// IF you are using int64_t as the data type, use the following line
|
||||||
|
//auto data_ptr = X_contig.data_ptr<int64_t>();
|
||||||
|
//std::vector<std::vector<int64_t>> data(X.size(0), std::vector<int64_t>(X.size(1)));
|
||||||
|
|
||||||
|
// Prepare output container
|
||||||
|
std::vector<std::vector<int>> data(X.size(0), std::vector<int>(X.size(1)));
|
||||||
|
|
||||||
|
// Fill the 2D vector in a single loop using pointer arithmetic
|
||||||
|
int rows = X.size(0);
|
||||||
|
int cols = X.size(1);
|
||||||
|
for (int i = 0; i < rows; ++i) {
|
||||||
|
std::copy(data_ptr + i * cols, data_ptr + (i + 1) * cols, data[i].begin());
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
static std::vector<T> to_vector(const torch::Tensor& y)
|
||||||
|
{
|
||||||
|
// Ensure the tensor is contiguous in memory
|
||||||
|
auto y_contig = y.contiguous();
|
||||||
|
|
||||||
|
// Access data pointer
|
||||||
|
auto data_ptr = y_contig.data_ptr<T>();
|
||||||
|
|
||||||
|
// Prepare output container
|
||||||
|
std::vector<T> data(y.size(0));
|
||||||
|
|
||||||
|
// Copy data efficiently
|
||||||
|
std::copy(data_ptr, data_ptr + y.size(0), data.begin());
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TENSORUTILS_HPP
|
@@ -5,6 +5,7 @@
|
|||||||
// ***************************************************************
|
// ***************************************************************
|
||||||
|
|
||||||
#include "XA1DE.h"
|
#include "XA1DE.h"
|
||||||
|
#include "TensorUtils.hpp"
|
||||||
|
|
||||||
namespace platform {
|
namespace platform {
|
||||||
XA1DE::XA1DE() : semaphore_{ CountingSemaphore::getInstance() }
|
XA1DE::XA1DE() : semaphore_{ CountingSemaphore::getInstance() }
|
||||||
@@ -32,6 +33,7 @@ namespace platform {
|
|||||||
instances.push_back(y);
|
instances.push_back(y);
|
||||||
int num_instances = instances[0].size();
|
int num_instances = instances[0].size();
|
||||||
int num_attributes = instances.size();
|
int num_attributes = instances.size();
|
||||||
|
|
||||||
normalize_weights(num_instances);
|
normalize_weights(num_instances);
|
||||||
std::vector<int> statesv;
|
std::vector<int> statesv;
|
||||||
for (int i = 0; i < num_attributes; i++) {
|
for (int i = 0; i < num_attributes; i++) {
|
||||||
@@ -166,47 +168,6 @@ namespace platform {
|
|||||||
return static_cast<float>(correct) / predictions.size();
|
return static_cast<float>(correct) / predictions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<int>> XA1DE::to_matrix(const torch::Tensor& X)
|
|
||||||
{
|
|
||||||
// Ensure tensor is contiguous in memory
|
|
||||||
auto X_contig = X.contiguous();
|
|
||||||
|
|
||||||
// Access tensor data pointer directly
|
|
||||||
auto data_ptr = X_contig.data_ptr<int>();
|
|
||||||
|
|
||||||
// IF you are using int64_t as the data type, use the following line
|
|
||||||
//auto data_ptr = X_contig.data_ptr<int64_t>();
|
|
||||||
//std::vector<std::vector<int64_t>> data(X.size(0), std::vector<int64_t>(X.size(1)));
|
|
||||||
|
|
||||||
// Prepare output container
|
|
||||||
std::vector<std::vector<int>> data(X.size(0), std::vector<int>(X.size(1)));
|
|
||||||
|
|
||||||
// Fill the 2D vector in a single loop using pointer arithmetic
|
|
||||||
int rows = X.size(0);
|
|
||||||
int cols = X.size(1);
|
|
||||||
for (int i = 0; i < rows; ++i) {
|
|
||||||
std::copy(data_ptr + i * cols, data_ptr + (i + 1) * cols, data[i].begin());
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
std::vector<T> XA1DE::to_vector(const torch::Tensor& y)
|
|
||||||
{
|
|
||||||
// Ensure the tensor is contiguous in memory
|
|
||||||
auto y_contig = y.contiguous();
|
|
||||||
|
|
||||||
// Access data pointer
|
|
||||||
auto data_ptr = y_contig.data_ptr<T>();
|
|
||||||
|
|
||||||
// Prepare output container
|
|
||||||
std::vector<T> data(y.size(0));
|
|
||||||
|
|
||||||
// Copy data efficiently
|
|
||||||
std::copy(data_ptr, data_ptr + y.size(0), data.begin());
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// statistics
|
// statistics
|
||||||
//
|
//
|
||||||
@@ -233,8 +194,8 @@ namespace platform {
|
|||||||
// fit(std::vector<std::vector<int>>& X, std::vector<int>& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
// fit(std::vector<std::vector<int>>& X, std::vector<int>& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
||||||
XA1DE& XA1DE::fit(torch::Tensor& X, torch::Tensor& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
XA1DE& XA1DE::fit(torch::Tensor& X, torch::Tensor& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
||||||
{
|
{
|
||||||
auto X_ = to_matrix(X);
|
auto X_ = TensorUtils::to_matrix(X);
|
||||||
auto y_ = to_vector<int>(y);
|
auto y_ = TensorUtils::to_vector<int>(y);
|
||||||
return fit(X_, y_, features, className, states, smoothing);
|
return fit(X_, y_, features, className, states, smoothing);
|
||||||
}
|
}
|
||||||
XA1DE& XA1DE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
XA1DE& XA1DE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
||||||
@@ -245,21 +206,55 @@ namespace platform {
|
|||||||
}
|
}
|
||||||
XA1DE& XA1DE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing)
|
XA1DE& XA1DE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing)
|
||||||
{
|
{
|
||||||
weights_ = to_vector<double>(weights);
|
weights_ = TensorUtils::to_vector<double>(weights);
|
||||||
return fit(dataset, features, className, states, smoothing);
|
return fit(dataset, features, className, states, smoothing);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Predict
|
// Predict
|
||||||
//
|
//
|
||||||
|
std::vector<int> XA1DE::predict_spode(std::vector<std::vector<int>>& test_data, int parent)
|
||||||
|
{
|
||||||
|
int test_size = test_data[0].size();
|
||||||
|
int sample_size = test_data.size();
|
||||||
|
auto predictions = std::vector<int>(test_size);
|
||||||
|
|
||||||
|
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<int>& 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_spode(instance, parent);
|
||||||
|
}
|
||||||
|
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(predictions));
|
||||||
|
}
|
||||||
|
for (auto& thread : threads) {
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
return predictions;
|
||||||
|
}
|
||||||
torch::Tensor XA1DE::predict(torch::Tensor& X)
|
torch::Tensor XA1DE::predict(torch::Tensor& X)
|
||||||
{
|
{
|
||||||
auto X_ = to_matrix(X);
|
auto X_ = TensorUtils::to_matrix(X);
|
||||||
torch::Tensor y = torch::tensor(predict(X_));
|
torch::Tensor y = torch::tensor(predict(X_));
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
torch::Tensor XA1DE::predict_proba(torch::Tensor& X)
|
torch::Tensor XA1DE::predict_proba(torch::Tensor& X)
|
||||||
{
|
{
|
||||||
auto X_ = to_matrix(X);
|
auto X_ = TensorUtils::to_matrix(X);
|
||||||
auto probabilities = predict_proba(X_);
|
auto probabilities = predict_proba(X_);
|
||||||
auto n_samples = X.size(1);
|
auto n_samples = X.size(1);
|
||||||
int n_classes = probabilities[0].size();
|
int n_classes = probabilities[0].size();
|
||||||
@@ -273,8 +268,8 @@ namespace platform {
|
|||||||
}
|
}
|
||||||
float XA1DE::score(torch::Tensor& X, torch::Tensor& y)
|
float XA1DE::score(torch::Tensor& X, torch::Tensor& y)
|
||||||
{
|
{
|
||||||
auto X_ = to_matrix(X);
|
auto X_ = TensorUtils::to_matrix(X);
|
||||||
auto y_ = to_vector<int>(y);
|
auto y_ = TensorUtils::to_vector<int>(y);
|
||||||
return score(X_, y_);
|
return score(X_, y_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@ namespace platform {
|
|||||||
std::vector<int> predict(std::vector<std::vector<int>>& X) override;
|
std::vector<int> predict(std::vector<std::vector<int>>& X) override;
|
||||||
torch::Tensor predict(torch::Tensor& X) override;
|
torch::Tensor predict(torch::Tensor& X) override;
|
||||||
torch::Tensor predict_proba(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_threads(const std::vector<std::vector<int>>& test_data);
|
std::vector<std::vector<double>> predict_proba_threads(const std::vector<std::vector<int>>& test_data);
|
||||||
std::vector<std::vector<double>> predict_proba(std::vector<std::vector<int>>& X) override;
|
std::vector<std::vector<double>> predict_proba(std::vector<std::vector<int>>& X) override;
|
||||||
float score(std::vector<std::vector<int>>& X, std::vector<int>& y) override;
|
float score(std::vector<std::vector<int>>& X, std::vector<int>& y) override;
|
||||||
@@ -47,7 +48,9 @@ namespace platform {
|
|||||||
std::vector<std::string>& getValidHyperparameters() { return validHyperparameters; }
|
std::vector<std::string>& getValidHyperparameters() { return validHyperparameters; }
|
||||||
void setDebug(bool debug) { this->debug = debug; }
|
void setDebug(bool debug) { this->debug = debug; }
|
||||||
std::vector<std::string> graph(const std::string& title = "") const override { return {}; }
|
std::vector<std::string> graph(const std::string& title = "") const override { return {}; }
|
||||||
void set_active_parents(std::vector<int> active_parents) { aode_.set_active_parents(active_parents); }
|
void set_active_parents(std::vector<int> active_parents) { for (const auto& parent : active_parents) aode_.set_active_parent(parent); }
|
||||||
|
void add_active_parent(int parent) { aode_.set_active_parent(parent); }
|
||||||
|
void remove_last_parent() { aode_.remove_last_parent(); }
|
||||||
protected:
|
protected:
|
||||||
void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override {};
|
void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override {};
|
||||||
|
|
||||||
@@ -64,9 +67,6 @@ namespace platform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename T>
|
|
||||||
std::vector<T> to_vector(const torch::Tensor& y);
|
|
||||||
std::vector<std::vector<int>> to_matrix(const torch::Tensor& X);
|
|
||||||
Xaode aode_;
|
Xaode aode_;
|
||||||
std::vector<double> weights_;
|
std::vector<double> weights_;
|
||||||
CountingSemaphore& semaphore_;
|
CountingSemaphore& semaphore_;
|
||||||
|
@@ -9,34 +9,23 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "XBAODE.h"
|
#include "XBAODE.h"
|
||||||
|
#include "TensorUtils.hpp"
|
||||||
|
|
||||||
namespace platform {
|
namespace platform {
|
||||||
XBAODE::XBAODE() : semaphore_{ CountingSemaphore::getInstance() }, Boost(false)
|
XBAODE::XBAODE() : semaphore_{ CountingSemaphore::getInstance() }, Boost(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
std::vector<int> XBAODE::initializeModels(const bayesnet::Smoothing_t smoothing)
|
void XBAODE::trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing)
|
||||||
{
|
{
|
||||||
torch::Tensor weights_ = torch::full({ m }, 1.0, torch::kFloat64);
|
|
||||||
std::vector<int> featuresSelected = featureSelection(weights_);
|
|
||||||
for (const int& feature : featuresSelected) {
|
|
||||||
// std::unique_ptr<Classifier> model = std::make_unique<SPODE>(feature);
|
|
||||||
// model->fit(dataset, features, className, states, weights_, smoothing);
|
|
||||||
// models.push_back(std::move(model));
|
|
||||||
significanceModels.push_back(1.0); // They will be updated later in trainModel
|
|
||||||
n_models++;
|
|
||||||
}
|
|
||||||
notes.push_back("Used features in initialization: " + std::to_string(featuresSelected.size()) + " of " + std::to_string(features.size()) + " with " + select_features_algorithm);
|
|
||||||
return featuresSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
XBAODE& XBAODE::fit(std::vector<std::vector<int>>& X, std::vector<int>& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
|
||||||
{
|
|
||||||
// aode_.fit(X, y, features, className, states, smoothing);
|
|
||||||
fitted = true;
|
fitted = true;
|
||||||
|
X_train_ = TensorUtils::to_matrix(X_train);
|
||||||
|
y_train_ = TensorUtils::to_vector<int>(y_train);
|
||||||
|
X_test_ = TensorUtils::to_matrix(X_test);
|
||||||
|
y_test_ = TensorUtils::to_vector<int>(y_test);
|
||||||
//
|
//
|
||||||
// Logging setup
|
// Logging setup
|
||||||
//
|
//
|
||||||
// loguru::set_thread_name("BoostAODE");
|
// loguru::set_thread_name("XBAODE");
|
||||||
// loguru::g_stderr_verbosity = loguru::Verbosity_OFF;
|
// loguru::g_stderr_verbosity = loguru::Verbosity_OFF;
|
||||||
// loguru::add_file("boostAODE.log", loguru::Truncate, loguru::Verbosity_MAX);
|
// loguru::add_file("boostAODE.log", loguru::Truncate, loguru::Verbosity_MAX);
|
||||||
|
|
||||||
@@ -46,16 +35,22 @@ namespace platform {
|
|||||||
torch::Tensor weights_ = torch::full({ m }, 1.0, torch::kFloat64);
|
torch::Tensor weights_ = torch::full({ m }, 1.0, torch::kFloat64);
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
std::vector<int> featuresUsed;
|
std::vector<int> featuresUsed;
|
||||||
|
int num_instances = m;
|
||||||
|
int num_attributes = n;
|
||||||
|
significanceModels.resize(num_attributes, 0.0);
|
||||||
|
aode_.fit(X_train_, y_train_, features, className, states, smoothing);
|
||||||
if (selectFeatures) {
|
if (selectFeatures) {
|
||||||
featuresUsed = initializeModels(smoothing);
|
featuresUsed = featureSelection(weights_);
|
||||||
auto ypred = predict(X_train);
|
aode_.set_active_parents(featuresUsed);
|
||||||
|
notes.push_back("Used features in initialization: " + std::to_string(featuresUsed.size()) + " of " + std::to_string(features.size()) + " with " + select_features_algorithm);
|
||||||
|
auto ypred = aode_.predict(X_train);
|
||||||
std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
|
std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
|
||||||
// Update significance of the models
|
// Update significance of the models
|
||||||
for (int i = 0; i < n_models; ++i) {
|
for (const auto& parent : featuresUsed) {
|
||||||
significanceModels[i] = alpha_t;
|
significanceModels[parent] = alpha_t;
|
||||||
}
|
}
|
||||||
if (finished) {
|
if (finished) {
|
||||||
return *this;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int numItemsPack = 0; // The counter of the models inserted in the current pack
|
int numItemsPack = 0; // The counter of the models inserted in the current pack
|
||||||
@@ -87,37 +82,35 @@ namespace platform {
|
|||||||
while (counter++ < k && featureSelection.size() > 0) {
|
while (counter++ < k && featureSelection.size() > 0) {
|
||||||
auto feature = featureSelection[0];
|
auto feature = featureSelection[0];
|
||||||
featureSelection.erase(featureSelection.begin());
|
featureSelection.erase(featureSelection.begin());
|
||||||
std::unique_ptr<Classifier> model;
|
aode_.add_active_parent(feature);
|
||||||
//model = std::make_unique<SPODE>(feature);
|
|
||||||
//model->fit(dataset, features, className, states, weights_, smoothing);
|
|
||||||
alpha_t = 0.0;
|
alpha_t = 0.0;
|
||||||
if (!block_update) {
|
if (!block_update) {
|
||||||
torch::Tensor ypred;
|
std::vector<int> ypred;
|
||||||
if (alpha_block) {
|
if (alpha_block) {
|
||||||
//
|
//
|
||||||
// Compute the prediction with the current ensemble + model
|
// Compute the prediction with the current ensemble + model
|
||||||
//
|
//
|
||||||
// Add the model to the ensemble
|
// Add the model to the ensemble
|
||||||
n_models++;
|
n_models++;
|
||||||
//models.push_back(std::move(model));
|
significanceModels[feature] = 1.0;
|
||||||
significanceModels.push_back(1);
|
aode_.add_active_parent(feature);
|
||||||
// Compute the prediction
|
// Compute the prediction
|
||||||
ypred = predict(X_train);
|
ypred = aode_.predict(X_train_);
|
||||||
// Remove the model from the ensemble
|
// Remove the model from the ensemble
|
||||||
//model = std::move(models.back());
|
significanceModels[feature] = 0.0;
|
||||||
models.pop_back();
|
aode_.remove_last_parent();
|
||||||
significanceModels.pop_back();
|
|
||||||
n_models--;
|
n_models--;
|
||||||
} else {
|
} else {
|
||||||
ypred = model->predict(X_train);
|
ypred = aode_.predict_spode(X_train_, feature);
|
||||||
}
|
}
|
||||||
// Step 3.1: Compute the classifier amout of say
|
// Step 3.1: Compute the classifier amout of say
|
||||||
std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred, weights_);
|
auto ypred_t = torch::tensor(ypred);
|
||||||
|
std::tie(weights_, alpha_t, finished) = update_weights(y_train, ypred_t, weights_);
|
||||||
}
|
}
|
||||||
// Step 3.4: Store classifier and its accuracy to weigh its future vote
|
// Step 3.4: Store classifier and its accuracy to weigh its future vote
|
||||||
numItemsPack++;
|
numItemsPack++;
|
||||||
featuresUsed.push_back(feature);
|
featuresUsed.push_back(feature);
|
||||||
//models.push_back(std::move(model));
|
aode_.add_active_parent(feature);
|
||||||
significanceModels.push_back(alpha_t);
|
significanceModels.push_back(alpha_t);
|
||||||
n_models++;
|
n_models++;
|
||||||
// VLOG_SCOPE_F(2, "numItemsPack: %d n_models: %d featuresUsed: %zu", numItemsPack, n_models, featuresUsed.size());
|
// VLOG_SCOPE_F(2, "numItemsPack: %d n_models: %d featuresUsed: %zu", numItemsPack, n_models, featuresUsed.size());
|
||||||
@@ -171,7 +164,7 @@ namespace platform {
|
|||||||
status = bayesnet::WARNING;
|
status = bayesnet::WARNING;
|
||||||
}
|
}
|
||||||
notes.push_back("Number of models: " + std::to_string(n_models));
|
notes.push_back("Number of models: " + std::to_string(n_models));
|
||||||
return *this;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -213,25 +206,6 @@ namespace platform {
|
|||||||
return aode_.getClassNumStates();
|
return aode_.getClassNumStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Fit
|
|
||||||
//
|
|
||||||
// fit(std::vector<std::vector<int>>& X, std::vector<int>& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
|
||||||
XBAODE& XBAODE::fit(torch::Tensor& X, torch::Tensor& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
|
||||||
{
|
|
||||||
aode_.fit(X, y, features, className, states, smoothing);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
XBAODE& XBAODE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing)
|
|
||||||
{
|
|
||||||
aode_.fit(dataset, features, className, states, smoothing);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
XBAODE& XBAODE::fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing)
|
|
||||||
{
|
|
||||||
aode_.fit(dataset, features, className, states, weights, smoothing);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// Predict
|
// Predict
|
||||||
//
|
//
|
||||||
|
@@ -17,21 +17,14 @@
|
|||||||
#include "XA1DE.h"
|
#include "XA1DE.h"
|
||||||
|
|
||||||
namespace platform {
|
namespace platform {
|
||||||
|
|
||||||
class XBAODE : public bayesnet::Boost {
|
class XBAODE : public bayesnet::Boost {
|
||||||
public:
|
public:
|
||||||
XBAODE();
|
XBAODE();
|
||||||
virtual ~XBAODE() = default;
|
virtual ~XBAODE() = default;
|
||||||
const std::string CLASSIFIER_NOT_FITTED = "Classifier has not been fitted";
|
const std::string CLASSIFIER_NOT_FITTED = "Classifier has not been fitted";
|
||||||
|
|
||||||
XBAODE& fit(std::vector<std::vector<int>>& X, std::vector<int>& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing) override;
|
|
||||||
XBAODE& fit(torch::Tensor& X, torch::Tensor& y, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing) override;
|
|
||||||
XBAODE& fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const bayesnet::Smoothing_t smoothing) override;
|
|
||||||
XBAODE& fit(torch::Tensor& dataset, const std::vector<std::string>& features, const std::string& className, std::map<std::string, std::vector<int>>& states, const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override;
|
|
||||||
std::vector<int> predict(std::vector<std::vector<int>>& X) override;
|
std::vector<int> predict(std::vector<std::vector<int>>& X) override;
|
||||||
torch::Tensor predict(torch::Tensor& X) override;
|
torch::Tensor predict(torch::Tensor& X) override;
|
||||||
torch::Tensor predict_proba(torch::Tensor& X) override;
|
torch::Tensor predict_proba(torch::Tensor& X) override;
|
||||||
std::vector<std::vector<double>> predict_proba_threads(const std::vector<std::vector<int>>& test_data);
|
|
||||||
std::vector<std::vector<double>> predict_proba(std::vector<std::vector<int>>& X) override;
|
std::vector<std::vector<double>> predict_proba(std::vector<std::vector<int>>& X) override;
|
||||||
float score(std::vector<std::vector<int>>& X, std::vector<int>& y) override;
|
float score(std::vector<std::vector<int>>& X, std::vector<int>& y) override;
|
||||||
float score(torch::Tensor& X, torch::Tensor& y) override;
|
float score(torch::Tensor& X, torch::Tensor& y) override;
|
||||||
@@ -50,10 +43,11 @@ namespace platform {
|
|||||||
std::vector<std::string> graph(const std::string& title = "") const override { return {}; }
|
std::vector<std::string> graph(const std::string& title = "") const override { return {}; }
|
||||||
void set_active_parents(std::vector<int> active_parents) { aode_.set_active_parents(active_parents); }
|
void set_active_parents(std::vector<int> active_parents) { aode_.set_active_parents(active_parents); }
|
||||||
protected:
|
protected:
|
||||||
void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override {};
|
void trainModel(const torch::Tensor& weights, const bayesnet::Smoothing_t smoothing) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> initializeModels(const bayesnet::Smoothing_t smoothing);
|
std::vector<std::vector<int>> X_train_, X_test_;
|
||||||
|
std::vector<int> y_train_, y_test_;
|
||||||
|
torch::Tensor dataset;
|
||||||
XA1DE aode_;
|
XA1DE aode_;
|
||||||
int n_models;
|
int n_models;
|
||||||
std::vector<double> weights_;
|
std::vector<double> weights_;
|
||||||
|
@@ -49,6 +49,9 @@ namespace platform {
|
|||||||
//
|
//
|
||||||
void init(const std::vector<int>& states)
|
void init(const std::vector<int>& states)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Check Valid input data
|
||||||
|
//
|
||||||
if (matrixState_ != MatrixState::EMPTY) {
|
if (matrixState_ != MatrixState::EMPTY) {
|
||||||
throw std::logic_error("Xaode: already initialized.");
|
throw std::logic_error("Xaode: already initialized.");
|
||||||
}
|
}
|
||||||
@@ -61,6 +64,10 @@ namespace platform {
|
|||||||
if (statesClass_ <= 0) {
|
if (statesClass_ <= 0) {
|
||||||
throw std::invalid_argument("Xaode: class states must be > 0.");
|
throw std::invalid_argument("Xaode: class states must be > 0.");
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// Initialize data structures
|
||||||
|
//
|
||||||
|
active_parents.resize(nFeatures_);
|
||||||
int totalStates = std::accumulate(states.begin(), states.end(), 0) - statesClass_;
|
int totalStates = std::accumulate(states.begin(), states.end(), 0) - statesClass_;
|
||||||
|
|
||||||
// For p(x_i=si | c), we store them in a 1D array classFeatureProbs_ after we compute.
|
// For p(x_i=si | c), we store them in a 1D array classFeatureProbs_ after we compute.
|
||||||
@@ -322,6 +329,11 @@ namespace platform {
|
|||||||
normalize(scores);
|
normalize(scores);
|
||||||
return scores;
|
return scores;
|
||||||
}
|
}
|
||||||
|
int predict_spode(const std::vector<int>& instance, int parent) const
|
||||||
|
{
|
||||||
|
auto probs = predict_proba_spode(instance, parent);
|
||||||
|
return (int)std::distance(probs.begin(), std::max_element(probs.begin(), probs.end()));
|
||||||
|
}
|
||||||
std::vector<double> predict_proba(std::vector<int>& instance)
|
std::vector<double> predict_proba(std::vector<int>& instance)
|
||||||
{
|
{
|
||||||
Timer timer;
|
Timer timer;
|
||||||
@@ -346,6 +358,10 @@ namespace platform {
|
|||||||
duration_first += timer.getDuration(); timer.start();
|
duration_first += timer.getDuration(); timer.start();
|
||||||
int idx, base, sp, sc, parent_offset;
|
int idx, base, sp, sc, parent_offset;
|
||||||
for (int parent = 1; parent < nFeatures_; ++parent) {
|
for (int parent = 1; parent < nFeatures_; ++parent) {
|
||||||
|
// if parent is not in the active_parents, skip it
|
||||||
|
if (std::find(active_parents.begin(), active_parents.end(), parent) == active_parents.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
sp = instance[parent];
|
sp = instance[parent];
|
||||||
parent_offset = pairOffset_[featureClassOffset_[parent] + sp];
|
parent_offset = pairOffset_[featureClassOffset_[parent] + sp];
|
||||||
for (int child = 0; child < parent; ++child) {
|
for (int child = 0; child < parent; ++child) {
|
||||||
@@ -552,9 +568,13 @@ namespace platform {
|
|||||||
{
|
{
|
||||||
return (nFeatures_ + 1) * nFeatures_;
|
return (nFeatures_ + 1) * nFeatures_;
|
||||||
}
|
}
|
||||||
void set_active_parents(std::vector<int> active_parents)
|
void set_active_parent(int active_parent)
|
||||||
{
|
{
|
||||||
this->active_parents = active_parents;
|
active_parents.push_back(active_parent);
|
||||||
|
}
|
||||||
|
void remove_last_parent()
|
||||||
|
{
|
||||||
|
active_parents.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user