Add KDBNew fix computeCPT error
This commit is contained in:
parent
a1c6ab18f3
commit
1a09ccca4c
3
Makefile
3
Makefile
@ -14,6 +14,9 @@ setup: ## Install dependencies for tests and coverage
|
||||
dependency: ## Create a dependency graph diagram of the project (build/dependency.png)
|
||||
cd build && cmake .. --graphviz=dependency.dot && dot -Tpng dependency.dot -o dependency.png
|
||||
|
||||
build: ## Build the main and BayesNetSample
|
||||
cmake --build build -t main -t BayesNetSample -j 32
|
||||
|
||||
debug: ## Build a debug version of the project
|
||||
@echo ">>> Building Debug BayesNet ...";
|
||||
@if [ -d ./build ]; then rm -rf ./build; fi
|
||||
|
112
sample/sample.cc
112
sample/sample.cc
@ -178,61 +178,59 @@ int main(int argc, char** argv)
|
||||
cout << "end." << endl;
|
||||
auto score = clf->score(Xd, y);
|
||||
cout << "Score: " << score << endl;
|
||||
auto graph = clf->graph();
|
||||
auto dot_file = model_name + "_" + file_name;
|
||||
ofstream file(dot_file + ".dot");
|
||||
file << graph;
|
||||
file.close();
|
||||
cout << "Graph saved in " << model_name << "_" << file_name << ".dot" << endl;
|
||||
cout << "dot -Tpng -o " + dot_file + ".png " + dot_file + ".dot " << endl;
|
||||
string stratified_string = stratified ? " Stratified" : "";
|
||||
cout << nFolds << " Folds" << stratified_string << " Cross validation" << endl;
|
||||
cout << "==========================================" << endl;
|
||||
torch::Tensor Xt = torch::zeros({ static_cast<int>(Xd.size()), static_cast<int>(Xd[0].size()) }, torch::kInt32);
|
||||
torch::Tensor yt = torch::tensor(y, torch::kInt32);
|
||||
for (int i = 0; i < features.size(); ++i) {
|
||||
Xt.index_put_({ i, "..." }, torch::tensor(Xd[i], torch::kInt32));
|
||||
}
|
||||
float total_score = 0, total_score_train = 0, score_train, score_test;
|
||||
Fold* fold;
|
||||
if (stratified)
|
||||
fold = new StratifiedKFold(nFolds, y, seed);
|
||||
else
|
||||
fold = new KFold(nFolds, y.size(), seed);
|
||||
for (auto i = 0; i < nFolds; ++i) {
|
||||
auto [train, test] = fold->getFold(i);
|
||||
cout << "Fold: " << i + 1 << endl;
|
||||
if (tensors) {
|
||||
auto ttrain = torch::tensor(train, torch::kInt64);
|
||||
auto ttest = torch::tensor(test, torch::kInt64);
|
||||
torch::Tensor Xtraint = torch::index_select(Xt, 1, ttrain);
|
||||
torch::Tensor ytraint = yt.index({ ttrain });
|
||||
torch::Tensor Xtestt = torch::index_select(Xt, 1, ttest);
|
||||
torch::Tensor ytestt = yt.index({ ttest });
|
||||
clf->fit(Xtraint, ytraint, features, className, states);
|
||||
auto temp = clf->predict(Xtraint);
|
||||
score_train = clf->score(Xtraint, ytraint);
|
||||
score_test = clf->score(Xtestt, ytestt);
|
||||
} else {
|
||||
auto [Xtrain, ytrain] = extract_indices(train, Xd, y);
|
||||
auto [Xtest, ytest] = extract_indices(test, Xd, y);
|
||||
clf->fit(Xtrain, ytrain, features, className, states);
|
||||
|
||||
score_train = clf->score(Xtrain, ytrain);
|
||||
score_test = clf->score(Xtest, ytest);
|
||||
}
|
||||
if (dump_cpt) {
|
||||
cout << "--- CPT Tables ---" << endl;
|
||||
clf->dump_cpt();
|
||||
}
|
||||
total_score_train += score_train;
|
||||
total_score += score_test;
|
||||
cout << "Score Train: " << score_train << endl;
|
||||
cout << "Score Test : " << score_test << endl;
|
||||
cout << "-------------------------------------------------------------------------------" << endl;
|
||||
}
|
||||
cout << "**********************************************************************************" << endl;
|
||||
cout << "Average Score Train: " << total_score_train / nFolds << endl;
|
||||
cout << "Average Score Test : " << total_score / nFolds << endl;
|
||||
return 0;
|
||||
// auto graph = clf->graph();
|
||||
// auto dot_file = model_name + "_" + file_name;
|
||||
// ofstream file(dot_file + ".dot");
|
||||
// file << graph;
|
||||
// file.close();
|
||||
// cout << "Graph saved in " << model_name << "_" << file_name << ".dot" << endl;
|
||||
// cout << "dot -Tpng -o " + dot_file + ".png " + dot_file + ".dot " << endl;
|
||||
// string stratified_string = stratified ? " Stratified" : "";
|
||||
// cout << nFolds << " Folds" << stratified_string << " Cross validation" << endl;
|
||||
// cout << "==========================================" << endl;
|
||||
// torch::Tensor Xt = torch::zeros({ static_cast<int>(Xd.size()), static_cast<int>(Xd[0].size()) }, torch::kInt32);
|
||||
// torch::Tensor yt = torch::tensor(y, torch::kInt32);
|
||||
// for (int i = 0; i < features.size(); ++i) {
|
||||
// Xt.index_put_({ i, "..." }, torch::tensor(Xd[i], torch::kInt32));
|
||||
// }
|
||||
// float total_score = 0, total_score_train = 0, score_train, score_test;
|
||||
// Fold* fold;
|
||||
// if (stratified)
|
||||
// fold = new StratifiedKFold(nFolds, y, seed);
|
||||
// else
|
||||
// fold = new KFold(nFolds, y.size(), seed);
|
||||
// for (auto i = 0; i < nFolds; ++i) {
|
||||
// auto [train, test] = fold->getFold(i);
|
||||
// cout << "Fold: " << i + 1 << endl;
|
||||
// if (tensors) {
|
||||
// auto ttrain = torch::tensor(train, torch::kInt64);
|
||||
// auto ttest = torch::tensor(test, torch::kInt64);
|
||||
// torch::Tensor Xtraint = torch::index_select(Xt, 1, ttrain);
|
||||
// torch::Tensor ytraint = yt.index({ ttrain });
|
||||
// torch::Tensor Xtestt = torch::index_select(Xt, 1, ttest);
|
||||
// torch::Tensor ytestt = yt.index({ ttest });
|
||||
// clf->fit(Xtraint, ytraint, features, className, states);
|
||||
// auto temp = clf->predict(Xtraint);
|
||||
// score_train = clf->score(Xtraint, ytraint);
|
||||
// score_test = clf->score(Xtestt, ytestt);
|
||||
// } else {
|
||||
// auto [Xtrain, ytrain] = extract_indices(train, Xd, y);
|
||||
// auto [Xtest, ytest] = extract_indices(test, Xd, y);
|
||||
// clf->fit(Xtrain, ytrain, features, className, states);
|
||||
// score_train = clf->score(Xtrain, ytrain);
|
||||
// score_test = clf->score(Xtest, ytest);
|
||||
// }
|
||||
// if (dump_cpt) {
|
||||
// cout << "--- CPT Tables ---" << endl;
|
||||
// clf->dump_cpt();
|
||||
// }
|
||||
// total_score_train += score_train;
|
||||
// total_score += score_test;
|
||||
// cout << "Score Train: " << score_train << endl;
|
||||
// cout << "Score Test : " << score_test << endl;
|
||||
// cout << "-------------------------------------------------------------------------------" << endl;
|
||||
// }
|
||||
// cout << "**********************************************************************************" << endl;
|
||||
// cout << "Average Score Train: " << total_score_train / nFolds << endl;
|
||||
// cout << "Average Score Test : " << total_score / nFolds << endl;return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
include_directories(${BayesNet_SOURCE_DIR}/lib/mdlp)
|
||||
include_directories(${BayesNet_SOURCE_DIR}/lib/Files)
|
||||
add_library(BayesNet bayesnetUtils.cc Network.cc Node.cc BayesMetrics.cc Classifier.cc KDB.cc TAN.cc SPODE.cc Ensemble.cc AODE.cc TANNew.cc Mst.cc Proposal.cc)
|
||||
add_library(BayesNet bayesnetUtils.cc Network.cc Node.cc BayesMetrics.cc Classifier.cc KDB.cc TAN.cc SPODE.cc Ensemble.cc AODE.cc TANNew.cc KDBNew.cc Mst.cc Proposal.cc)
|
||||
target_link_libraries(BayesNet mdlp ArffFiles "${TORCH_LIBRARIES}")
|
@ -36,14 +36,18 @@ namespace bayesnet {
|
||||
yv = vector<int>(y.data_ptr<int>(), y.data_ptr<int>() + y.size(0));
|
||||
return build(features, className, states);
|
||||
}
|
||||
void Classifier::generateTensorXFromVector()
|
||||
{
|
||||
X = torch::zeros({ static_cast<int>(Xv.size()), static_cast<int>(Xv[0].size()) }, kInt32);
|
||||
for (int i = 0; i < Xv.size(); ++i) {
|
||||
X.index_put_({ i, "..." }, torch::tensor(Xv[i], kInt32));
|
||||
}
|
||||
}
|
||||
// X is nxm where n is the number of features and m the number of samples
|
||||
Classifier& Classifier::fit(vector<vector<int>>& X, vector<int>& y, vector<string>& features, string className, map<string, vector<int>>& states)
|
||||
{
|
||||
this->X = torch::zeros({ static_cast<int>(X.size()), static_cast<int>(X[0].size()) }, kInt32);
|
||||
Xv = X;
|
||||
for (int i = 0; i < X.size(); ++i) {
|
||||
this->X.index_put_({ i, "..." }, torch::tensor(X[i], kInt32));
|
||||
}
|
||||
generateTensorXFromVector();
|
||||
this->y = torch::tensor(y, kInt32);
|
||||
yv = y;
|
||||
return build(features, className, states);
|
||||
@ -112,11 +116,9 @@ namespace bayesnet {
|
||||
{
|
||||
// Add all nodes to the network
|
||||
for (const auto& feature : features) {
|
||||
model.addNode(feature, states[feature].size());
|
||||
cout << "-Adding node " << feature << " with " << states[feature].size() << " states" << endl;
|
||||
model.addNode(feature);
|
||||
}
|
||||
model.addNode(className, states[className].size());
|
||||
cout << "*Adding class " << className << " with " << states[className].size() << " states" << endl;
|
||||
model.addNode(className);
|
||||
}
|
||||
int Classifier::getNumberOfNodes()
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ namespace bayesnet {
|
||||
string className;
|
||||
map<string, vector<int>> states;
|
||||
void checkFitParameters();
|
||||
void generateTensorXFromVector();
|
||||
virtual void train() = 0;
|
||||
public:
|
||||
Classifier(Network model);
|
||||
|
@ -35,6 +35,7 @@ namespace bayesnet {
|
||||
}
|
||||
// 2. Compute class conditional mutual information I(Xi;XjIC), f or each
|
||||
auto conditionalEdgeWeights = metrics.conditionalEdge();
|
||||
cout << "Conditional edge weights: " << conditionalEdgeWeights << endl;
|
||||
// 3. Let the used variable list, S, be empty.
|
||||
vector<int> S;
|
||||
// 4. Let the DAG network being constructed, BN, begin with a single
|
||||
|
48
src/BayesNet/KDBNew.cc
Normal file
48
src/BayesNet/KDBNew.cc
Normal file
@ -0,0 +1,48 @@
|
||||
#include "KDBNew.h"
|
||||
|
||||
namespace bayesnet {
|
||||
using namespace std;
|
||||
KDBNew::KDBNew(int k) : KDB(k), Proposal(KDB::Xv, KDB::yv, features, className) {}
|
||||
KDBNew& KDBNew::fit(torch::Tensor& X_, torch::Tensor& y_, vector<string>& features_, string className_, map<string, vector<int>>& states_)
|
||||
{
|
||||
// This first part should go in a Classifier method called fit_local_discretization o fit_float...
|
||||
features = features_;
|
||||
className = className_;
|
||||
Xf = X_;
|
||||
y = y_;
|
||||
model.initialize();
|
||||
// Fills vectors Xv & yv with the data from tensors X_ (discretized) & y
|
||||
fit_local_discretization(states, y);
|
||||
generateTensorXFromVector();
|
||||
// We have discretized the input data
|
||||
// 1st we need to fit the model to build the normal TAN structure, TAN::fit initializes the base Bayesian network
|
||||
cout << "KDBNew: Fitting model" << endl;
|
||||
KDB::fit(KDB::Xv, KDB::yv, features, className, states);
|
||||
cout << "KDBNew: Model fitted" << endl;
|
||||
localDiscretizationProposal(states, model);
|
||||
generateTensorXFromVector();
|
||||
Tensor ytmp = torch::transpose(y.view({ y.size(0), 1 }), 0, 1);
|
||||
samples = torch::cat({ X, ytmp }, 0);
|
||||
model.fit(KDB::Xv, KDB::yv, features, className);
|
||||
return *this;
|
||||
}
|
||||
void KDBNew::train()
|
||||
{
|
||||
KDB::train();
|
||||
}
|
||||
Tensor KDBNew::predict(Tensor& X)
|
||||
{
|
||||
auto Xtd = torch::zeros_like(X, torch::kInt32);
|
||||
for (int i = 0; i < X.size(0); ++i) {
|
||||
auto Xt = vector<float>(X[i].data_ptr<float>(), X[i].data_ptr<float>() + X.size(1));
|
||||
auto Xd = discretizers[features[i]]->transform(Xt);
|
||||
Xtd.index_put_({ i }, torch::tensor(Xd, torch::kInt32));
|
||||
}
|
||||
cout << "KDBNew Xtd: " << Xtd.sizes() << endl;
|
||||
return KDB::predict(Xtd);
|
||||
}
|
||||
vector<string> KDBNew::graph(const string& name)
|
||||
{
|
||||
return KDB::graph(name);
|
||||
}
|
||||
}
|
20
src/BayesNet/KDBNew.h
Normal file
20
src/BayesNet/KDBNew.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef KDBNEW_H
|
||||
#define KDBNEW_H
|
||||
#include "KDB.h"
|
||||
#include "Proposal.h"
|
||||
|
||||
namespace bayesnet {
|
||||
using namespace std;
|
||||
class KDBNew : public KDB, public Proposal {
|
||||
private:
|
||||
public:
|
||||
KDBNew(int k);
|
||||
virtual ~KDBNew() = default;
|
||||
KDBNew& fit(torch::Tensor& X, torch::Tensor& y, vector<string>& features, string className, map<string, vector<int>>& states) override;
|
||||
vector<string> graph(const string& name = "KDB") override;
|
||||
Tensor predict(Tensor& X) override;
|
||||
void train() override;
|
||||
static inline string version() { return "0.0.1"; };
|
||||
};
|
||||
}
|
||||
#endif // !KDBNew_H
|
@ -31,21 +31,18 @@ namespace bayesnet {
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
void Network::addNode(const string& name, int numStates)
|
||||
void Network::addNode(const string& name)
|
||||
{
|
||||
if (name == "") {
|
||||
throw invalid_argument("Node name cannot be empty");
|
||||
}
|
||||
if (nodes.find(name) != nodes.end()) {
|
||||
return;
|
||||
}
|
||||
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 and remove parents, children and CPT
|
||||
nodes[name]->clear();
|
||||
nodes[name]->setNumStates(numStates);
|
||||
return;
|
||||
}
|
||||
nodes[name] = std::make_unique<Node>(name, numStates);
|
||||
nodes[name] = std::make_unique<Node>(name);
|
||||
}
|
||||
vector<string> Network::getFeatures()
|
||||
{
|
||||
@ -128,14 +125,20 @@ namespace bayesnet {
|
||||
}
|
||||
}
|
||||
}
|
||||
void Network::setStates()
|
||||
{
|
||||
// Set states to every Node in the network
|
||||
for (int i = 0; i < features.size(); ++i) {
|
||||
nodes[features[i]]->setNumStates(static_cast<int>(torch::max(samples.index({ i, "..." })).item<int>()) + 1);
|
||||
}
|
||||
classNumStates = nodes[className]->getNumStates();
|
||||
}
|
||||
// X comes in nxm, where n is the number of features and m the number of samples
|
||||
void Network::fit(torch::Tensor& X, torch::Tensor& y, const vector<string>& featureNames, const string& className)
|
||||
{
|
||||
checkFitData(X.size(1), X.size(0), y.size(0), featureNames, className);
|
||||
this->className = className;
|
||||
dataset.clear();
|
||||
// Specific part
|
||||
classNumStates = torch::max(y).item<int>() + 1;
|
||||
Tensor ytmp = torch::transpose(y.view({ y.size(0), 1 }), 0, 1);
|
||||
samples = torch::cat({ X , ytmp }, 0);
|
||||
for (int i = 0; i < featureNames.size(); ++i) {
|
||||
@ -151,8 +154,6 @@ namespace bayesnet {
|
||||
checkFitData(input_data[0].size(), input_data.size(), labels.size(), featureNames, className);
|
||||
this->className = className;
|
||||
dataset.clear();
|
||||
// Specific part
|
||||
classNumStates = *max_element(labels.begin(), labels.end()) + 1;
|
||||
// Build dataset & tensor of samples (nxm) (n+1 because of the class)
|
||||
samples = torch::zeros({ static_cast<int>(input_data.size() + 1), static_cast<int>(input_data[0].size()) }, torch::kInt32);
|
||||
for (int i = 0; i < featureNames.size(); ++i) {
|
||||
@ -165,6 +166,7 @@ namespace bayesnet {
|
||||
}
|
||||
void Network::completeFit()
|
||||
{
|
||||
setStates();
|
||||
int maxThreadsRunning = static_cast<int>(std::thread::hardware_concurrency() * maxThreads);
|
||||
if (maxThreadsRunning < 1) {
|
||||
maxThreadsRunning = 1;
|
||||
@ -213,7 +215,7 @@ namespace bayesnet {
|
||||
auto sample = samples.index({ "...", i });
|
||||
auto psample = predict_sample(sample);
|
||||
auto temp = torch::tensor(psample, torch::kFloat64);
|
||||
// result.index_put_({ i, "..." }, torch::tensor(predict_sample(sample), torch::kFloat64));
|
||||
// result.index_put_({ i, "..." }, torch::tensor(predict_sample(sample), torch::kFloat64));
|
||||
result.index_put_({ i, "..." }, temp);
|
||||
}
|
||||
if (proba)
|
||||
@ -325,17 +327,17 @@ namespace bayesnet {
|
||||
vector<thread> threads;
|
||||
mutex mtx;
|
||||
for (int i = 0; i < classNumStates; ++i) {
|
||||
// threads.emplace_back([this, &result, &evidence, i, &mtx]() {
|
||||
auto completeEvidence = map<string, int>(evidence);
|
||||
completeEvidence[getClassName()] = i;
|
||||
threads.emplace_back([this, &result, &evidence, i, &mtx]() {
|
||||
auto completeEvidence = map<string, int>(evidence);
|
||||
completeEvidence[getClassName()] = i;
|
||||
double factor = computeFactor(completeEvidence);
|
||||
// lock_guard<mutex> lock(mtx);
|
||||
lock_guard<mutex> lock(mtx);
|
||||
result[i] = factor;
|
||||
// });
|
||||
});
|
||||
}
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
// for (auto& thread : threads) {
|
||||
// thread.join();
|
||||
// }
|
||||
// Normalize result
|
||||
double sum = accumulate(result.begin(), result.end(), 0.0);
|
||||
transform(result.begin(), result.end(), result.begin(), [sum](double& value) { return value / sum; });
|
||||
@ -421,7 +423,7 @@ namespace bayesnet {
|
||||
void Network::dump_cpt()
|
||||
{
|
||||
for (auto& node : nodes) {
|
||||
cout << "* " << node.first << ": " << node.second->getCPT() << endl;
|
||||
cout << "* " << node.first << ": (" << node.second->getNumStates() << ") : " << node.second->getCPT().sizes() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace bayesnet {
|
||||
double mutualInformation(torch::Tensor&, torch::Tensor&);
|
||||
void completeFit();
|
||||
void checkFitData(int n_features, int n_samples, int n_samples_y, const vector<string>& featureNames, const string& className);
|
||||
void setStates();
|
||||
public:
|
||||
Network();
|
||||
explicit Network(float, int);
|
||||
@ -34,7 +35,7 @@ namespace bayesnet {
|
||||
explicit Network(Network&);
|
||||
torch::Tensor& getSamples();
|
||||
float getmaxThreads();
|
||||
void addNode(const string&, int);
|
||||
void addNode(const string&);
|
||||
void addEdge(const string&, const string&);
|
||||
map<string, std::unique_ptr<Node>>& getNodes();
|
||||
vector<string> getFeatures();
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace bayesnet {
|
||||
|
||||
Node::Node(const std::string& name, int numStates)
|
||||
: name(name), numStates(numStates), cpTable(torch::Tensor()), parents(vector<Node*>()), children(vector<Node*>())
|
||||
Node::Node(const std::string& name)
|
||||
: name(name), numStates(0), cpTable(torch::Tensor()), parents(vector<Node*>()), children(vector<Node*>())
|
||||
{
|
||||
}
|
||||
void Node::clear()
|
||||
@ -86,6 +86,7 @@ namespace bayesnet {
|
||||
}
|
||||
void Node::computeCPT(map<string, vector<int>>& dataset, const int laplaceSmoothing)
|
||||
{
|
||||
dimensions.clear();
|
||||
// Get dimensions of the CPT
|
||||
dimensions.push_back(numStates);
|
||||
transform(parents.begin(), parents.end(), back_inserter(dimensions), [](const auto& parent) { return parent->getNumStates(); });
|
||||
|
@ -16,7 +16,7 @@ namespace bayesnet {
|
||||
vector<int64_t> dimensions; // dimensions of the cpTable
|
||||
public:
|
||||
vector<pair<string, string>> combinations(const vector<string>&);
|
||||
Node(const string&, int);
|
||||
explicit Node(const string&);
|
||||
void clear();
|
||||
void addParent(Node*);
|
||||
void addChild(Node*);
|
||||
|
@ -2,22 +2,26 @@
|
||||
|
||||
namespace bayesnet {
|
||||
using namespace std;
|
||||
TANNew::TANNew() : TAN(), Proposal(TAN::Xv, TAN::yv, TAN::features, TAN::className) {}
|
||||
TANNew::TANNew() : TAN(), Proposal(TAN::Xv, TAN::yv, features, className) {}
|
||||
TANNew& TANNew::fit(torch::Tensor& X_, torch::Tensor& y_, vector<string>& features_, string className_, map<string, vector<int>>& states_)
|
||||
{
|
||||
// This first part should go in a Classifier method called fit_local_discretization o fit_float...
|
||||
TAN::features = features_;
|
||||
TAN::className = className_;
|
||||
features = features_;
|
||||
className = className_;
|
||||
Xf = X_;
|
||||
y = y_;
|
||||
// Fills vectors Xv & yv with the data from tensors X_ (discretized) & y
|
||||
fit_local_discretization(states, y);
|
||||
generateTensorXFromVector();
|
||||
// We have discretized the input data
|
||||
// 1st we need to fit the model to build the normal TAN structure, TAN::fit initializes the base Bayesian network
|
||||
cout << "TANNew: Fitting model" << endl;
|
||||
TAN::fit(TAN::Xv, TAN::yv, TAN::features, TAN::className, states);
|
||||
TAN::fit(TAN::Xv, TAN::yv, features, className, states);
|
||||
cout << "TANNew: Model fitted" << endl;
|
||||
localDiscretizationProposal(states, model);
|
||||
addNodes();
|
||||
generateTensorXFromVector();
|
||||
Tensor ytmp = torch::transpose(y.view({ y.size(0), 1 }), 0, 1);
|
||||
samples = torch::cat({ X, ytmp }, 0);
|
||||
model.fit(TAN::Xv, TAN::yv, features, className);
|
||||
return *this;
|
||||
}
|
||||
|
@ -146,6 +146,11 @@ namespace platform {
|
||||
auto y_test = y.index({ test_t });
|
||||
cout << nfold + 1 << ", " << flush;
|
||||
clf->fit(X_train, y_train, features, className, states);
|
||||
cout << endl;
|
||||
auto lines = clf->show();
|
||||
for (auto line : lines) {
|
||||
cout << line << endl;
|
||||
}
|
||||
nodes[item] = clf->getNumberOfNodes();
|
||||
edges[item] = clf->getNumberOfEdges();
|
||||
num_states[item] = clf->getNumberOfStates();
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "KDB.h"
|
||||
#include "SPODE.h"
|
||||
#include "TANNew.h"
|
||||
#include "KDBNew.h"
|
||||
namespace platform {
|
||||
class Models {
|
||||
private:
|
||||
|
@ -8,6 +8,8 @@ static platform::Registrar registrarS("SPODE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::SPODE(2);});
|
||||
static platform::Registrar registrarK("KDB",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::KDB(2);});
|
||||
static platform::Registrar registrarKN("KDBNew",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::KDBNew(2);});
|
||||
static platform::Registrar registrarA("AODE",
|
||||
[](void) -> bayesnet::BaseClassifier* { return new bayesnet::AODE();});
|
||||
#endif
|
@ -9,29 +9,21 @@ 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);
|
||||
net.addNode("A");
|
||||
net.addNode("B");
|
||||
REQUIRE(net.getFeatures() == vector<string>{"A", "B"});
|
||||
net.addNode("C", 2);
|
||||
net.addNode("C");
|
||||
REQUIRE(net.getFeatures() == vector<string>{"A", "B", "C"});
|
||||
}
|
||||
SECTION("Test get edges")
|
||||
{
|
||||
auto net = bayesnet::Network();
|
||||
net.addNode("A", 3);
|
||||
net.addNode("B", 5);
|
||||
net.addNode("C", 2);
|
||||
net.addNode("A");
|
||||
net.addNode("B");
|
||||
net.addNode("C");
|
||||
net.addEdge("A", "B");
|
||||
net.addEdge("B", "C");
|
||||
REQUIRE(net.getEdges() == vector<pair<string, string>>{ {"A", "B"}, { "B", "C" } });
|
||||
|
Loading…
Reference in New Issue
Block a user