Optimize BoostAODE -> XBAODE #33

Merged
rmontanana merged 27 commits from WA2DE into main 2025-03-16 17:58:10 +00:00
48 changed files with 3049 additions and 470 deletions
Showing only changes of commit 9ee388561f - Show all commits

View File

@@ -7,15 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [1.0.7] 2025-03-16
### Added ### Added
- Add a new hyperparameter to the BoostAODE class, *alphablock*, to control the way α is computed, with the last model or with the ensmble built so far. Default value is *false*. - A new hyperparameter to the BoostAODE class, *alphablock*, to control the way α is computed, with the last model or with the ensmble built so far. Default value is *false*.
- Add a new hyperparameter to the SPODE class, *parent*, to set the root node of the model. If no value is set the root parameter of the constructor is used. - A new hyperparameter to the SPODE class, *parent*, to set the root node of the model. If no value is set the root parameter of the constructor is used.
- Add a new hyperparameter to the TAN class, *parent*, to set the root node of the model. If not set the first feature is used as root. - A new hyperparameter to the TAN class, *parent*, to set the root node of the model. If not set the first feature is used as root.
- A new model named XSPODE, an optimized for speed averaged one dependence estimator.
- A new model named XSP2DE, an optimized for speed averaged two dependence estimator.
- A new model named XBAODE, an optimized for speed BoostAODE model.
- A new model named XBA2DE, an optimized for speed BoostA2DE model.
### Internal ### Internal
- Optimize ComputeCPT method in the Node class. - Optimize ComputeCPT method in the Node class.
- Add methods getCount and getMaxCount to the CountingSemaphore class, returning the current count and the maximum count of threads respectively.
### Changed ### Changed

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
project(BayesNet project(BayesNet
VERSION 1.0.6 VERSION 1.0.7
DESCRIPTION "Bayesian Network and basic classifiers Library." DESCRIPTION "Bayesian Network and basic classifiers Library."
HOMEPAGE_URL "https://github.com/rmontanana/bayesnet" HOMEPAGE_URL "https://github.com/rmontanana/bayesnet"
LANGUAGES CXX LANGUAGES CXX

View File

@@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// *************************************************************** // ***************************************************************
#include "XSPnDE.h" #include "XSP2DE.h"
#include <pthread.h> // for pthread_setname_np on linux #include <pthread.h> // for pthread_setname_np on linux
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
@@ -18,7 +18,7 @@ namespace bayesnet {
// -------------------------------------- // --------------------------------------
// Constructor // Constructor
// -------------------------------------- // --------------------------------------
XSpnde::XSpnde(int spIndex1, int spIndex2) XSp2de::XSp2de(int spIndex1, int spIndex2)
: superParent1_{ spIndex1 } : superParent1_{ spIndex1 }
, superParent2_{ spIndex2 } , superParent2_{ spIndex2 }
, nFeatures_{0} , nFeatures_{0}
@@ -34,7 +34,7 @@ XSpnde::XSpnde(int spIndex1, int spIndex2)
// -------------------------------------- // --------------------------------------
// setHyperparameters // setHyperparameters
// -------------------------------------- // --------------------------------------
void XSpnde::setHyperparameters(const nlohmann::json &hyperparameters_) void XSp2de::setHyperparameters(const nlohmann::json &hyperparameters_)
{ {
auto hyperparameters = hyperparameters_; auto hyperparameters = hyperparameters_;
if (hyperparameters.contains("parent1")) { if (hyperparameters.contains("parent1")) {
@@ -52,7 +52,7 @@ void XSpnde::setHyperparameters(const nlohmann::json &hyperparameters_)
// -------------------------------------- // --------------------------------------
// fitx // fitx
// -------------------------------------- // --------------------------------------
void XSpnde::fitx(torch::Tensor & X, torch::Tensor & y, void XSp2de::fitx(torch::Tensor & X, torch::Tensor & y,
torch::Tensor & weights_, const Smoothing_t smoothing) torch::Tensor & weights_, const Smoothing_t smoothing)
{ {
m = X.size(1); // number of samples m = X.size(1); // number of samples
@@ -73,7 +73,7 @@ void XSpnde::fitx(torch::Tensor & X, torch::Tensor & y,
// -------------------------------------- // --------------------------------------
// buildModel // buildModel
// -------------------------------------- // --------------------------------------
void XSpnde::buildModel(const torch::Tensor &weights) void XSp2de::buildModel(const torch::Tensor &weights)
{ {
nFeatures_ = n; nFeatures_ = n;
@@ -122,7 +122,7 @@ void XSpnde::buildModel(const torch::Tensor &weights)
// -------------------------------------- // --------------------------------------
// trainModel // trainModel
// -------------------------------------- // --------------------------------------
void XSpnde::trainModel(const torch::Tensor &weights, void XSp2de::trainModel(const torch::Tensor &weights,
const bayesnet::Smoothing_t smoothing) const bayesnet::Smoothing_t smoothing)
{ {
// Accumulate raw counts // Accumulate raw counts
@@ -158,7 +158,7 @@ void XSpnde::trainModel(const torch::Tensor &weights,
// -------------------------------------- // --------------------------------------
// addSample // addSample
// -------------------------------------- // --------------------------------------
void XSpnde::addSample(const std::vector<int> &instance, double weight) void XSp2de::addSample(const std::vector<int> &instance, double weight)
{ {
if (weight <= 0.0) if (weight <= 0.0)
return; return;
@@ -205,7 +205,7 @@ void XSpnde::addSample(const std::vector<int> &instance, double weight)
// -------------------------------------- // --------------------------------------
// computeProbabilities // computeProbabilities
// -------------------------------------- // --------------------------------------
void XSpnde::computeProbabilities() void XSp2de::computeProbabilities()
{ {
double totalCount = std::accumulate(classCounts_.begin(), double totalCount = std::accumulate(classCounts_.begin(),
classCounts_.end(), 0.0); classCounts_.end(), 0.0);
@@ -305,7 +305,7 @@ void XSpnde::computeProbabilities()
// -------------------------------------- // --------------------------------------
// predict_proba (single instance) // predict_proba (single instance)
// -------------------------------------- // --------------------------------------
std::vector<double> XSpnde::predict_proba(const std::vector<int> &instance) const std::vector<double> XSp2de::predict_proba(const std::vector<int> &instance) const
{ {
if (!fitted) { if (!fitted) {
throw std::logic_error(CLASSIFIER_NOT_FITTED); throw std::logic_error(CLASSIFIER_NOT_FITTED);
@@ -355,7 +355,7 @@ std::vector<double> XSpnde::predict_proba(const std::vector<int> &instance) cons
// -------------------------------------- // --------------------------------------
// predict_proba (batch) // predict_proba (batch)
// -------------------------------------- // --------------------------------------
std::vector<std::vector<double>> XSpnde::predict_proba(std::vector<std::vector<int>> &test_data) std::vector<std::vector<double>> XSp2de::predict_proba(std::vector<std::vector<int>> &test_data)
{ {
int test_size = test_data[0].size(); // each feature is test_data[f], size = #samples int test_size = test_data[0].size(); // each feature is test_data[f], size = #samples
int sample_size = test_data.size(); // = nFeatures_ int sample_size = test_data.size(); // = nFeatures_
@@ -372,7 +372,7 @@ std::vector<std::vector<double>> XSpnde::predict_proba(std::vector<std::vector<i
int sample_size, int sample_size,
std::vector<std::vector<double>> &predictions) { std::vector<std::vector<double>> &predictions) {
std::string threadName = std::string threadName =
"XSpnde-" + std::to_string(begin) + "-" + std::to_string(chunk); "XSp2de-" + std::to_string(begin) + "-" + std::to_string(chunk);
#if defined(__linux__) #if defined(__linux__)
pthread_setname_np(pthread_self(), threadName.c_str()); pthread_setname_np(pthread_self(), threadName.c_str());
#else #else
@@ -404,7 +404,7 @@ std::vector<std::vector<double>> XSpnde::predict_proba(std::vector<std::vector<i
// -------------------------------------- // --------------------------------------
// predict (single instance) // predict (single instance)
// -------------------------------------- // --------------------------------------
int XSpnde::predict(const std::vector<int> &instance) const int XSp2de::predict(const std::vector<int> &instance) const
{ {
auto p = predict_proba(instance); auto p = predict_proba(instance);
return static_cast<int>( return static_cast<int>(
@@ -415,7 +415,7 @@ int XSpnde::predict(const std::vector<int> &instance) const
// -------------------------------------- // --------------------------------------
// predict (batch of data) // predict (batch of data)
// -------------------------------------- // --------------------------------------
std::vector<int> XSpnde::predict(std::vector<std::vector<int>> &test_data) std::vector<int> XSp2de::predict(std::vector<std::vector<int>> &test_data)
{ {
auto probabilities = predict_proba(test_data); auto probabilities = predict_proba(test_data);
std::vector<int> predictions(probabilities.size(), 0); std::vector<int> predictions(probabilities.size(), 0);
@@ -433,7 +433,7 @@ std::vector<int> XSpnde::predict(std::vector<std::vector<int>> &test_data)
// -------------------------------------- // --------------------------------------
// predict (torch::Tensor version) // predict (torch::Tensor version)
// -------------------------------------- // --------------------------------------
torch::Tensor XSpnde::predict(torch::Tensor &X) torch::Tensor XSp2de::predict(torch::Tensor &X)
{ {
auto X_ = TensorUtils::to_matrix(X); auto X_ = TensorUtils::to_matrix(X);
auto result_v = predict(X_); auto result_v = predict(X_);
@@ -443,7 +443,7 @@ torch::Tensor XSpnde::predict(torch::Tensor &X)
// -------------------------------------- // --------------------------------------
// predict_proba (torch::Tensor version) // predict_proba (torch::Tensor version)
// -------------------------------------- // --------------------------------------
torch::Tensor XSpnde::predict_proba(torch::Tensor &X) torch::Tensor XSp2de::predict_proba(torch::Tensor &X)
{ {
auto X_ = TensorUtils::to_matrix(X); auto X_ = TensorUtils::to_matrix(X);
auto result_v = predict_proba(X_); auto result_v = predict_proba(X_);
@@ -459,7 +459,7 @@ torch::Tensor XSpnde::predict_proba(torch::Tensor &X)
// -------------------------------------- // --------------------------------------
// score (torch::Tensor version) // score (torch::Tensor version)
// -------------------------------------- // --------------------------------------
float XSpnde::score(torch::Tensor &X, torch::Tensor &y) float XSp2de::score(torch::Tensor &X, torch::Tensor &y)
{ {
torch::Tensor y_pred = predict(X); torch::Tensor y_pred = predict(X);
return (y_pred == y).sum().item<float>() / y.size(0); return (y_pred == y).sum().item<float>() / y.size(0);
@@ -468,7 +468,7 @@ float XSpnde::score(torch::Tensor &X, torch::Tensor &y)
// -------------------------------------- // --------------------------------------
// score (vector version) // score (vector version)
// -------------------------------------- // --------------------------------------
float XSpnde::score(std::vector<std::vector<int>> &X, std::vector<int> &y) float XSp2de::score(std::vector<std::vector<int>> &X, std::vector<int> &y)
{ {
auto y_pred = predict(X); auto y_pred = predict(X);
int correct = 0; int correct = 0;
@@ -483,7 +483,7 @@ float XSpnde::score(std::vector<std::vector<int>> &X, std::vector<int> &y)
// -------------------------------------- // --------------------------------------
// Utility: normalize // Utility: normalize
// -------------------------------------- // --------------------------------------
void XSpnde::normalize(std::vector<double> &v) const void XSp2de::normalize(std::vector<double> &v) const
{ {
double sum = 0.0; double sum = 0.0;
for (auto &val : v) { for (auto &val : v) {
@@ -499,10 +499,10 @@ void XSpnde::normalize(std::vector<double> &v) const
// -------------------------------------- // --------------------------------------
// to_string // to_string
// -------------------------------------- // --------------------------------------
std::string XSpnde::to_string() const std::string XSp2de::to_string() const
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "----- XSpnde Model -----\n" oss << "----- XSp2de Model -----\n"
<< "nFeatures_ = " << nFeatures_ << "\n" << "nFeatures_ = " << nFeatures_ << "\n"
<< "superParent1_ = " << superParent1_ << "\n" << "superParent1_ = " << superParent1_ << "\n"
<< "superParent2_ = " << superParent2_ << "\n" << "superParent2_ = " << superParent2_ << "\n"
@@ -533,30 +533,30 @@ std::string XSpnde::to_string() const
// -------------------------------------- // --------------------------------------
// Some introspection about the graph // Some introspection about the graph
// -------------------------------------- // --------------------------------------
int XSpnde::getNumberOfNodes() const int XSp2de::getNumberOfNodes() const
{ {
// nFeatures + 1 class node // nFeatures + 1 class node
return nFeatures_ + 1; return nFeatures_ + 1;
} }
int XSpnde::getClassNumStates() const int XSp2de::getClassNumStates() const
{ {
return statesClass_; return statesClass_;
} }
int XSpnde::getNFeatures() const int XSp2de::getNFeatures() const
{ {
return nFeatures_; return nFeatures_;
} }
int XSpnde::getNumberOfStates() const int XSp2de::getNumberOfStates() const
{ {
// purely an example. Possibly you want to sum up actual // purely an example. Possibly you want to sum up actual
// cardinalities or something else. // cardinalities or something else.
return std::accumulate(states_.begin(), states_.end(), 0) * nFeatures_; return std::accumulate(states_.begin(), states_.end(), 0) * nFeatures_;
} }
int XSpnde::getNumberOfEdges() const int XSp2de::getNumberOfEdges() const
{ {
// In an SPNDE with n=2, for each feature we have edges from class, sp1, sp2. // In an SPNDE with n=2, for each feature we have edges from class, sp1, sp2.
// So thats 3*(nFeatures_) edges, minus the ones for the superparents themselves, // So thats 3*(nFeatures_) edges, minus the ones for the superparents themselves,

View File

@@ -4,8 +4,8 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// *************************************************************** // ***************************************************************
#ifndef XSPNDE_H #ifndef XSP2DE_H
#define XSPNDE_H #define XSP2DE_H
#include "Classifier.h" #include "Classifier.h"
#include "bayesnet/utils/CountingSemaphore.h" #include "bayesnet/utils/CountingSemaphore.h"
@@ -14,9 +14,9 @@
namespace bayesnet { namespace bayesnet {
class XSpnde : public Classifier { class XSp2de : public Classifier {
public: public:
XSpnde(int spIndex1, int spIndex2); XSp2de(int spIndex1, int spIndex2);
void setHyperparameters(const nlohmann::json &hyperparameters_) override; void setHyperparameters(const nlohmann::json &hyperparameters_) override;
void fitx(torch::Tensor &X, torch::Tensor &y, torch::Tensor &weights_, const Smoothing_t smoothing); void fitx(torch::Tensor &X, torch::Tensor &y, torch::Tensor &weights_, const Smoothing_t smoothing);
std::vector<double> predict_proba(const std::vector<int> &instance) const; std::vector<double> predict_proba(const std::vector<int> &instance) const;
@@ -72,4 +72,4 @@ class XSpnde : public Classifier {
}; };
} // namespace bayesnet } // namespace bayesnet
#endif // XSPNDE_H #endif // XSP2DE_H

View File

@@ -7,7 +7,7 @@
#include <folding.hpp> #include <folding.hpp>
#include <limits.h> #include <limits.h>
#include "XBA2DE.h" #include "XBA2DE.h"
#include "bayesnet/classifiers/XSPnDE.h" #include "bayesnet/classifiers/XSP2DE.h"
#include "bayesnet/utils/TensorUtils.h" #include "bayesnet/utils/TensorUtils.h"
namespace bayesnet { namespace bayesnet {
@@ -23,7 +23,7 @@ std::vector<int> XBA2DE::initializeModels(const Smoothing_t smoothing) {
} }
for (int i = 0; i < featuresSelected.size() - 1; i++) { for (int i = 0; i < featuresSelected.size() - 1; i++) {
for (int j = i + 1; j < featuresSelected.size(); j++) { for (int j = i + 1; j < featuresSelected.size(); j++) {
std::unique_ptr<Classifier> model = std::make_unique<XSpnde>(featuresSelected[i], featuresSelected[j]); std::unique_ptr<Classifier> model = std::make_unique<XSp2de>(featuresSelected[i], featuresSelected[j]);
model->fit(dataset, features, className, states, weights_, smoothing); model->fit(dataset, features, className, states, weights_, smoothing);
add_model(std::move(model), 1.0); add_model(std::move(model), 1.0);
} }
@@ -94,7 +94,7 @@ void XBA2DE::trainModel(const torch::Tensor &weights, const Smoothing_t smoothin
auto feature_pair = pairSelection[0]; auto feature_pair = pairSelection[0];
pairSelection.erase(pairSelection.begin()); pairSelection.erase(pairSelection.begin());
std::unique_ptr<Classifier> model; std::unique_ptr<Classifier> model;
model = std::make_unique<XSpnde>(feature_pair.first, feature_pair.second); model = std::make_unique<XSp2de>(feature_pair.first, feature_pair.second);
model->fit(dataset, features, className, states, weights_, smoothing); model->fit(dataset, features, className, states, weights_, smoothing);
alpha_t = 0.0; alpha_t = 0.0;
if (!block_update) { if (!block_update) {

View File

@@ -20,7 +20,7 @@
#include "bayesnet/ensembles/AODELd.h" #include "bayesnet/ensembles/AODELd.h"
#include "bayesnet/ensembles/BoostAODE.h" #include "bayesnet/ensembles/BoostAODE.h"
const std::string ACTUAL_VERSION = "1.0.6"; const std::string ACTUAL_VERSION = "1.0.7";
TEST_CASE("Test Bayesian Classifiers score & version", "[Models]") TEST_CASE("Test Bayesian Classifiers score & version", "[Models]")
{ {

View File

@@ -7,7 +7,7 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp> #include <catch2/catch_approx.hpp>
#include <catch2/matchers/catch_matchers.hpp> #include <catch2/matchers/catch_matchers.hpp>
#include "bayesnet/classifiers/XSPnDE.h" // <-- your new 2-superparent classifier #include "bayesnet/classifiers/XSP2DE.h" // <-- your new 2-superparent classifier
#include "TestUtils.h" // for RawDatasets, etc. #include "TestUtils.h" // for RawDatasets, etc.
// Helper function to handle each (sp1, sp2) pair in tests // Helper function to handle each (sp1, sp2) pair in tests
@@ -19,7 +19,7 @@ static void check_spnde_pair(
bool fitTensor) bool fitTensor)
{ {
// Create our classifier // Create our classifier
bayesnet::XSpnde clf(sp1, sp2); bayesnet::XSp2de clf(sp1, sp2);
// Option A: fit with vector-based data // Option A: fit with vector-based data
if (fitVector) { if (fitVector) {
@@ -48,7 +48,7 @@ static void check_spnde_pair(
// ------------------------------------------------------------ // ------------------------------------------------------------
// 1) Fit vector test // 1) Fit vector test
// ------------------------------------------------------------ // ------------------------------------------------------------
TEST_CASE("fit vector test (XSPNDE)", "[XSPNDE]") { TEST_CASE("fit vector test (XSP2DE)", "[XSP2DE]") {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
std::vector<std::pair<int,int>> parentPairs = { std::vector<std::pair<int,int>> parentPairs = {
@@ -62,7 +62,7 @@ TEST_CASE("fit vector test (XSPNDE)", "[XSPNDE]") {
// ------------------------------------------------------------ // ------------------------------------------------------------
// 2) Fit dataset test // 2) Fit dataset test
// ------------------------------------------------------------ // ------------------------------------------------------------
TEST_CASE("fit dataset test (XSPNDE)", "[XSPNDE]") { TEST_CASE("fit dataset test (XSP2DE)", "[XSP2DE]") {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
// Again test multiple pairs: // Again test multiple pairs:
@@ -77,7 +77,7 @@ TEST_CASE("fit dataset test (XSPNDE)", "[XSPNDE]") {
// ------------------------------------------------------------ // ------------------------------------------------------------
// 3) Tensors dataset predict & predict_proba // 3) Tensors dataset predict & predict_proba
// ------------------------------------------------------------ // ------------------------------------------------------------
TEST_CASE("tensors dataset predict & predict_proba (XSPNDE)", "[XSPNDE]") { TEST_CASE("tensors dataset predict & predict_proba (XSP2DE)", "[XSP2DE]") {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
std::vector<std::pair<int,int>> parentPairs = { std::vector<std::pair<int,int>> parentPairs = {
@@ -85,7 +85,7 @@ TEST_CASE("tensors dataset predict & predict_proba (XSPNDE)", "[XSPNDE]") {
}; };
for (auto &p : parentPairs) { for (auto &p : parentPairs) {
bayesnet::XSpnde clf(p.first, p.second); bayesnet::XSp2de clf(p.first, p.second);
clf.fit(raw.Xt, raw.yt, raw.features, raw.className, raw.states, raw.smoothing); clf.fit(raw.Xt, raw.yt, raw.features, raw.className, raw.states, raw.smoothing);
REQUIRE(clf.getNumberOfNodes() == 5); REQUIRE(clf.getNumberOfNodes() == 5);
@@ -100,26 +100,26 @@ TEST_CASE("tensors dataset predict & predict_proba (XSPNDE)", "[XSPNDE]") {
auto proba = clf.predict_proba(X_reduced); auto proba = clf.predict_proba(X_reduced);
} }
} }
TEST_CASE("Check hyperparameters", "[XSPNDE]") TEST_CASE("Check hyperparameters", "[XSP2DE]")
{ {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
auto clf = bayesnet::XSpnde(0, 1); auto clf = bayesnet::XSp2de(0, 1);
clf.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, raw.smoothing); clf.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, raw.smoothing);
auto clf2 = bayesnet::XSpnde(2, 3); auto clf2 = bayesnet::XSp2de(2, 3);
clf2.setHyperparameters({{"parent1", 0}, {"parent2", 1}}); clf2.setHyperparameters({{"parent1", 0}, {"parent2", 1}});
clf2.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, raw.smoothing); clf2.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, raw.smoothing);
REQUIRE(clf.to_string() == clf2.to_string()); REQUIRE(clf.to_string() == clf2.to_string());
} }
TEST_CASE("Check different smoothing", "[XSPNDE]") TEST_CASE("Check different smoothing", "[XSP2DE]")
{ {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
auto clf = bayesnet::XSpnde(0, 1); auto clf = bayesnet::XSp2de(0, 1);
clf.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::ORIGINAL); clf.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::ORIGINAL);
auto clf2 = bayesnet::XSpnde(0, 1); auto clf2 = bayesnet::XSp2de(0, 1);
clf2.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::LAPLACE); clf2.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::LAPLACE);
auto clf3 = bayesnet::XSpnde(0, 1); auto clf3 = bayesnet::XSp2de(0, 1);
clf3.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::NONE); clf3.fit(raw.Xv, raw.yv, raw.features, raw.className, raw.states, bayesnet::Smoothing_t::NONE);
auto score = clf.score(raw.X_test, raw.y_test); auto score = clf.score(raw.X_test, raw.y_test);
auto score2 = clf2.score(raw.X_test, raw.y_test); auto score2 = clf2.score(raw.X_test, raw.y_test);
@@ -128,10 +128,10 @@ TEST_CASE("Check different smoothing", "[XSPNDE]")
REQUIRE(score2 == Catch::Approx(0.7333333).epsilon(raw.epsilon)); REQUIRE(score2 == Catch::Approx(0.7333333).epsilon(raw.epsilon));
REQUIRE(score3 == Catch::Approx(0.966667).epsilon(raw.epsilon)); REQUIRE(score3 == Catch::Approx(0.966667).epsilon(raw.epsilon));
} }
TEST_CASE("Check rest", "[XSPNDE]") TEST_CASE("Check rest", "[XSP2DE]")
{ {
auto raw = RawDatasets("iris", true); auto raw = RawDatasets("iris", true);
auto clf = bayesnet::XSpnde(0, 1); auto clf = bayesnet::XSp2de(0, 1);
REQUIRE_THROWS_AS(clf.predict_proba(std::vector<int>({1,2,3,4})), std::logic_error); REQUIRE_THROWS_AS(clf.predict_proba(std::vector<int>({1,2,3,4})), std::logic_error);
clf.fitx(raw.Xt, raw.yt, raw.weights, bayesnet::Smoothing_t::ORIGINAL); clf.fitx(raw.Xt, raw.yt, raw.weights, bayesnet::Smoothing_t::ORIGINAL);
REQUIRE(clf.getNFeatures() == 4); REQUIRE(clf.getNFeatures() == 4);