From 1a21015492fb0236874ae58e37924238f42bba6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Montan=CC=83ana?= Date: Tue, 18 Jul 2023 13:44:08 +0200 Subject: [PATCH] Add some tests --- src/Network.cc | 3 +++ tests/BayesNetwork.cc | 32 +++++++++++++++++++++++++++--- tests/CMakeLists.txt | 2 +- tests/main.cc | 46 +++---------------------------------------- tests/utils.cc | 43 +++++++++++++++++++++++++++++++++++++--- tests/utils.h | 15 +++++++++----- 6 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/Network.cc b/src/Network.cc index e3246d4..b6cda9c 100644 --- a/src/Network.cc +++ b/src/Network.cc @@ -21,6 +21,9 @@ namespace bayesnet { } void Network::addNode(string name, int numStates) { + if (find(features.begin(), features.end(), name) == features.end()) { + features.push_back(name); + } if (nodes.find(name) != nodes.end()) { // if node exists update its number of states nodes[name]->setNumStates(numStates); diff --git a/tests/BayesNetwork.cc b/tests/BayesNetwork.cc index 528a41d..b6bda60 100644 --- a/tests/BayesNetwork.cc +++ b/tests/BayesNetwork.cc @@ -1,3 +1,29 @@ -// -// Created by Ricardo Montañana Gómez on 18/7/23. -// +#include +#include +#include +#include +#include "../src/KDB.h" +#include "utils.h" + +TEST_CASE("Test Bayesian Network") +{ + auto[Xd, y, features, className, states] = loadFile("iris"); + + SECTION("Test Update Nodes") + { + auto net = bayesnet::Network(); + net.addNode("A", 3); + REQUIRE(net.getStates() == 3); + net.addNode("A", 5); + REQUIRE(net.getStates() == 5); + } + SECTION("Test get features") + { + auto net = bayesnet::Network(); + net.addNode("A", 3); + net.addNode("B", 5); + REQUIRE(net.getFeatures() == vector{"A", "B"}); + net.addNode("C", 2); + REQUIRE(net.getFeatures() == vector{"A", "B", "C"}); + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 14ff9bb..e7f0438 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ if(ENABLE_TESTING) set(TEST_MAIN "unit_tests") set(TEST_SOURCES main.cc ../sample/ArffFiles.cc ../sample/CPPFImdlp.cpp ../sample/Metrics.cpp ../src/utils.cc ../src/Network.cc ../src/Node.cc ../src/Metrics.cc ../src/BaseClassifier.cc ../src/KDB.cc - ../src/TAN.cc ../src/SPODE.cc ../src/Ensemble.cc ../src/AODE.cc ../src/Mst.cc) + ../src/TAN.cc ../src/SPODE.cc ../src/Ensemble.cc ../src/AODE.cc ../src/Mst.cc BayesNetwork.cc utils.cc utils.h) add_executable(${TEST_MAIN} ${TEST_SOURCES}) target_link_libraries(${TEST_MAIN} PUBLIC "${TORCH_LIBRARIES}" Catch2::Catch2WithMain) add_test(NAME ${TEST_MAIN} COMMAND ${TEST_MAIN}) diff --git a/tests/main.cc b/tests/main.cc index 31454b0..4dfe3d2 100644 --- a/tests/main.cc +++ b/tests/main.cc @@ -5,35 +5,14 @@ #include #include #include -#include -#include "../sample/ArffFiles.h" -#include "../sample/CPPFImdlp.h" #include "../src/KDB.h" #include "../src/TAN.h" #include "../src/SPODE.h" #include "../src/AODE.h" - -const string PATH = "data/"; -using namespace std; - -pair, map> discretize(vector& X, mdlp::labels_t& y, vector features) -{ - vectorXd; - map maxes; - - auto fimdlp = mdlp::CPPFImdlp(); - for (int i = 0; i < X.size(); i++) { - fimdlp.fit(X[i], y); - mdlp::labels_t& xd = fimdlp.transform(X[i]); - maxes[features[i]] = *max_element(xd.begin(), xd.end()) + 1; - Xd.push_back(xd); - } - return { Xd, maxes }; -} +#include "utils.h" TEST_CASE("Test Bayesian Classifiers score", "[BayesNet]") { - auto path = "../../data/"; map , float> scores = { {{"diabetes", "AODE"}, 0.811198}, {{"diabetes", "KDB"}, 0.852865}, {{"diabetes", "SPODE"}, 0.802083}, {{"diabetes", "TAN"}, 0.821615}, {{"ecoli", "AODE"}, 0.889881}, {{"ecoli", "KDB"}, 0.889881}, {{"ecoli", "SPODE"}, 0.880952}, {{"ecoli", "TAN"}, 0.892857}, @@ -42,27 +21,8 @@ TEST_CASE("Test Bayesian Classifiers score", "[BayesNet]") }; string file_name = GENERATE("glass", "iris", "ecoli", "diabetes"); - auto handler = ArffFiles(); - handler.load(path + static_cast(file_name) + ".arff"); - // Get Dataset X, y - vector& X = handler.getX(); - mdlp::labels_t& y = handler.getY(); - // Get className & Features - auto className = handler.getClassName(); - vector features; - for (auto feature : handler.getAttributes()) { - features.push_back(feature.first); - } - // Discretize Dataset - vector Xd; - map maxes; - tie(Xd, maxes) = discretize(X, y, features); - maxes[className] = *max_element(y.begin(), y.end()) + 1; - map> states; - for (auto feature : features) { - states[feature] = vector(maxes[feature]); - } - states[className] = vector(maxes[className]); + auto[Xd, y, features, className, states] = loadFile(file_name); + SECTION("Test TAN classifier (" + file_name + ")") { auto clf = bayesnet::TAN(); diff --git a/tests/utils.cc b/tests/utils.cc index 528a41d..7e9cafb 100644 --- a/tests/utils.cc +++ b/tests/utils.cc @@ -1,3 +1,40 @@ -// -// Created by Ricardo Montañana Gómez on 18/7/23. -// +#include "utils.h" + +pair, map> discretize(vector &X, mdlp::labels_t &y, vector features) { + vector Xd; + map maxes; + auto fimdlp = mdlp::CPPFImdlp(); + for (int i = 0; i < X.size(); i++) { + fimdlp.fit(X[i], y); + mdlp::labels_t &xd = fimdlp.transform(X[i]); + maxes[features[i]] = *max_element(xd.begin(), xd.end()) + 1; + Xd.push_back(xd); + } + return {Xd, maxes}; +} + +tuple>, vector, vector, string, map>> +loadFile(string name) { + auto handler = ArffFiles(); + handler.load(PATH + static_cast(name) + ".arff"); + // Get Dataset X, y + vector &X = handler.getX(); + mdlp::labels_t &y = handler.getY(); + // Get className & Features + auto className = handler.getClassName(); + vector features; + for (auto feature: handler.getAttributes()) { + features.push_back(feature.first); + } + // Discretize Dataset + vector Xd; + map maxes; + tie(Xd, maxes) = discretize(X, y, features); + maxes[className] = *max_element(y.begin(), y. end()) + 1; + map> states; + for (auto feature: features) { + states[feature] = vector(maxes[feature]); + } + states[className] = vector(maxes[className]); + return {Xd, y, features, className, states}; +} \ No newline at end of file diff --git a/tests/utils.h b/tests/utils.h index 12b4f6c..5a826f4 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -1,8 +1,13 @@ -// -// Created by Ricardo Montañana Gómez on 18/7/23. -// - +#include +#include +#include +#include +#include "../sample/ArffFiles.h" +#include "../sample/CPPFImdlp.h" #ifndef BAYESNET_UTILS_H #define BAYESNET_UTILS_H - +using namespace std; +const string PATH = "../../data/"; +pair, map> discretize(vector &X, mdlp::labels_t &y, vector features); +tuple>, vector, vector, string, map>> loadFile(string name); #endif //BAYESNET_UTILS_H