From 1c6af619b579513615136968c82a699de7dedc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Montan=CC=83ana?= Date: Thu, 24 Aug 2023 12:09:35 +0200 Subject: [PATCH] Exception if hyperparameters not valid --- .clang-uml | 19 +++++++++++++++++++ src/BayesNet/AODE.h | 1 - src/BayesNet/AODELd.cc | 2 +- src/BayesNet/AODELd.h | 3 +-- src/BayesNet/Classifier.cc | 9 +++++++++ src/BayesNet/Classifier.h | 1 + src/BayesNet/KDBLd.cc | 2 +- src/BayesNet/KDBLd.h | 1 - src/BayesNet/Proposal.cc | 9 +++++++++ src/BayesNet/Proposal.h | 1 + src/BayesNet/SPODE.h | 1 - src/BayesNet/SPODELd.cc | 6 ++++-- src/BayesNet/SPODELd.h | 1 - src/BayesNet/TAN.h | 1 - src/BayesNet/TANLd.cc | 2 +- src/BayesNet/TANLd.h | 1 - 16 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 .clang-uml diff --git a/.clang-uml b/.clang-uml new file mode 100644 index 0000000..29fd166 --- /dev/null +++ b/.clang-uml @@ -0,0 +1,19 @@ +compilation_database_dir: build +output_directory: puml +diagrams: + myproject_class: + type: class + glob: + - src/bayesnet/*.cc + - src/platform/*.cc + using_namespace: bayesnet + include: + namespaces: + - bayesnet + - platform + exclude: + namespaces: + - myproject::detail + plantuml: + after: + - 'note left of {{ alias("MyProjectMain") }}: Main class of myproject library.' diff --git a/src/BayesNet/AODE.h b/src/BayesNet/AODE.h index 78c9876..00965f6 100644 --- a/src/BayesNet/AODE.h +++ b/src/BayesNet/AODE.h @@ -10,7 +10,6 @@ namespace bayesnet { AODE(); virtual ~AODE() {}; vector graph(const string& title = "AODE") const override; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; }; } #endif \ No newline at end of file diff --git a/src/BayesNet/AODELd.cc b/src/BayesNet/AODELd.cc index 439f2d4..1a3bd75 100644 --- a/src/BayesNet/AODELd.cc +++ b/src/BayesNet/AODELd.cc @@ -6,7 +6,7 @@ namespace bayesnet { AODELd::AODELd() : Ensemble(), Proposal(dataset, features, className) {} AODELd& AODELd::fit(torch::Tensor& X_, torch::Tensor& y_, const vector& features_, const string& className_, map>& states_) { - // This first part should go in a Classifier method called fit_local_discretization o fit_float... + checkInput(X_, y_); features = features_; className = className_; Xf = X_; diff --git a/src/BayesNet/AODELd.h b/src/BayesNet/AODELd.h index 125d819..cdb8822 100644 --- a/src/BayesNet/AODELd.h +++ b/src/BayesNet/AODELd.h @@ -14,9 +14,8 @@ namespace bayesnet { AODELd(); AODELd& fit(torch::Tensor& X_, torch::Tensor& y_, const vector& features_, const string& className_, map>& states_) override; virtual ~AODELd() = default; - vector graph(const string& name = "AODE") const override; + vector graph(const string& name = "AODELd") const override; static inline string version() { return "0.0.1"; }; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; }; } #endif // !AODELD_H \ No newline at end of file diff --git a/src/BayesNet/Classifier.cc b/src/BayesNet/Classifier.cc index 1100288..af9ab8c 100644 --- a/src/BayesNet/Classifier.cc +++ b/src/BayesNet/Classifier.cc @@ -71,6 +71,9 @@ namespace bayesnet { } void Classifier::checkFitParameters() { + if (torch::is_floating_point(dataset)) { + throw invalid_argument("dataset (X, y) must be of type Integer"); + } if (n != features.size()) { throw invalid_argument("X " + to_string(n) + " and features " + to_string(features.size()) + " must have the same number of features"); } @@ -160,4 +163,10 @@ namespace bayesnet { } } } + void Classifier::setHyperparameters(nlohmann::json& hyperparameters) + { + // Check if hyperparameters are valid, default is no hyperparameters + const vector validKeys = { }; + checkHyperparameters(validKeys, hyperparameters); + } } \ No newline at end of file diff --git a/src/BayesNet/Classifier.h b/src/BayesNet/Classifier.h index ba5dcbc..6be3300 100644 --- a/src/BayesNet/Classifier.h +++ b/src/BayesNet/Classifier.h @@ -43,6 +43,7 @@ namespace bayesnet { vector show() const override; vector topological_order() override; void dump_cpt() const override; + void setHyperparameters(nlohmann::json& hyperparameters) override; }; } #endif diff --git a/src/BayesNet/KDBLd.cc b/src/BayesNet/KDBLd.cc index 172045a..fc0910a 100644 --- a/src/BayesNet/KDBLd.cc +++ b/src/BayesNet/KDBLd.cc @@ -5,7 +5,7 @@ namespace bayesnet { KDBLd::KDBLd(int k) : KDB(k), Proposal(dataset, features, className) {} KDBLd& KDBLd::fit(torch::Tensor& X_, torch::Tensor& y_, const vector& features_, const string& className_, map>& states_) { - // This first part should go in a Classifier method called fit_local_discretization o fit_float... + checkInput(X_, y_); features = features_; className = className_; Xf = X_; diff --git a/src/BayesNet/KDBLd.h b/src/BayesNet/KDBLd.h index c642bad..c034938 100644 --- a/src/BayesNet/KDBLd.h +++ b/src/BayesNet/KDBLd.h @@ -13,7 +13,6 @@ namespace bayesnet { KDBLd& fit(torch::Tensor& X, torch::Tensor& y, const vector& features, const string& className, map>& states) override; vector graph(const string& name = "KDB") const override; Tensor predict(Tensor& X) override; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; static inline string version() { return "0.0.1"; }; }; } diff --git a/src/BayesNet/Proposal.cc b/src/BayesNet/Proposal.cc index c410289..09b39c3 100644 --- a/src/BayesNet/Proposal.cc +++ b/src/BayesNet/Proposal.cc @@ -9,6 +9,15 @@ namespace bayesnet { delete value; } } + void Proposal::checkInput(const torch::Tensor& X, const torch::Tensor& y) + { + if (!torch::is_floating_point(X)) { + throw std::invalid_argument("X must be a floating point tensor"); + } + if (torch::is_floating_point(y)) { + throw std::invalid_argument("y must be an integer tensor"); + } + } map> Proposal::localDiscretizationProposal(const map>& oldStates, Network& model) { // order of local discretization is important. no good 0, 1, 2... diff --git a/src/BayesNet/Proposal.h b/src/BayesNet/Proposal.h index f5eabda..e6ba2bc 100644 --- a/src/BayesNet/Proposal.h +++ b/src/BayesNet/Proposal.h @@ -13,6 +13,7 @@ namespace bayesnet { Proposal(torch::Tensor& pDataset, vector& features_, string& className_); virtual ~Proposal(); protected: + void checkInput(const torch::Tensor& X, const torch::Tensor& y); torch::Tensor prepareX(torch::Tensor& X); map> localDiscretizationProposal(const map>& states, Network& model); map> fit_local_discretization(const torch::Tensor& y); diff --git a/src/BayesNet/SPODE.h b/src/BayesNet/SPODE.h index c5a95e4..0a78830 100644 --- a/src/BayesNet/SPODE.h +++ b/src/BayesNet/SPODE.h @@ -12,7 +12,6 @@ namespace bayesnet { explicit SPODE(int root); virtual ~SPODE() {}; vector graph(const string& name = "SPODE") const override; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; }; } #endif \ No newline at end of file diff --git a/src/BayesNet/SPODELd.cc b/src/BayesNet/SPODELd.cc index eeb6e16..73b9d2b 100644 --- a/src/BayesNet/SPODELd.cc +++ b/src/BayesNet/SPODELd.cc @@ -5,7 +5,7 @@ namespace bayesnet { SPODELd::SPODELd(int root) : SPODE(root), Proposal(dataset, features, className) {} SPODELd& SPODELd::fit(torch::Tensor& X_, torch::Tensor& y_, const vector& features_, const string& className_, map>& states_) { - // This first part should go in a Classifier method called fit_local_discretization o fit_float... + checkInput(X_, y_); features = features_; className = className_; Xf = X_; @@ -20,9 +20,11 @@ namespace bayesnet { } SPODELd& SPODELd::fit(torch::Tensor& dataset, const vector& features_, const string& className_, map>& states_) { + if (!torch::is_floating_point(dataset)) { + throw std::runtime_error("Dataset must be a floating point tensor"); + } Xf = dataset.index({ torch::indexing::Slice(0, dataset.size(0) - 1), "..." }).clone(); y = dataset.index({ -1, "..." }).clone(); - // This first part should go in a Classifier method called fit_local_discretization o fit_float... features = features_; className = className_; // Fills vectors Xv & yv with the data from tensors X_ (discretized) & y diff --git a/src/BayesNet/SPODELd.h b/src/BayesNet/SPODELd.h index c83a6e9..b6121d9 100644 --- a/src/BayesNet/SPODELd.h +++ b/src/BayesNet/SPODELd.h @@ -13,7 +13,6 @@ namespace bayesnet { SPODELd& fit(torch::Tensor& dataset, const vector& features, const string& className, map>& states) override; vector graph(const string& name = "SPODE") const override; Tensor predict(Tensor& X) override; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; static inline string version() { return "0.0.1"; }; }; } diff --git a/src/BayesNet/TAN.h b/src/BayesNet/TAN.h index c8eea5f..60a5656 100644 --- a/src/BayesNet/TAN.h +++ b/src/BayesNet/TAN.h @@ -11,7 +11,6 @@ namespace bayesnet { TAN(); virtual ~TAN() {}; vector graph(const string& name = "TAN") const override; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; }; } #endif \ No newline at end of file diff --git a/src/BayesNet/TANLd.cc b/src/BayesNet/TANLd.cc index b0ceb96..320f756 100644 --- a/src/BayesNet/TANLd.cc +++ b/src/BayesNet/TANLd.cc @@ -5,7 +5,7 @@ namespace bayesnet { TANLd::TANLd() : TAN(), Proposal(dataset, features, className) {} TANLd& TANLd::fit(torch::Tensor& X_, torch::Tensor& y_, const vector& features_, const string& className_, map>& states_) { - // This first part should go in a Classifier method called fit_local_discretization o fit_float... + checkInput(X_, y_); features = features_; className = className_; Xf = X_; diff --git a/src/BayesNet/TANLd.h b/src/BayesNet/TANLd.h index 205ca6a..b218ae3 100644 --- a/src/BayesNet/TANLd.h +++ b/src/BayesNet/TANLd.h @@ -14,7 +14,6 @@ namespace bayesnet { vector graph(const string& name = "TAN") const override; Tensor predict(Tensor& X) override; static inline string version() { return "0.0.1"; }; - void setHyperparameters(nlohmann::json& hyperparameters) override {}; }; } #endif // !TANLD_H \ No newline at end of file