Add getNumberOfNodes & getNumberOfEdges to Models
Add some more tests
This commit is contained in:
parent
1a21015492
commit
2f5bd0ea7e
@ -1,4 +1,3 @@
|
|||||||
include_directories(${BayesNet_SOURCE_DIR}/src)
|
include_directories(${BayesNet_SOURCE_DIR}/src)
|
||||||
link_directories(${MyProject_SOURCE_DIR}/src)
|
|
||||||
add_executable(main main.cc ArffFiles.cc CPPFImdlp.cpp Metrics.cpp)
|
add_executable(main main.cc ArffFiles.cc CPPFImdlp.cpp Metrics.cpp)
|
||||||
target_link_libraries(main BayesNet "${TORCH_LIBRARIES}")
|
target_link_libraries(main BayesNet "${TORCH_LIBRARIES}")
|
@ -8,7 +8,6 @@ namespace bayesnet {
|
|||||||
BaseClassifier::BaseClassifier(Network model) : model(model), m(0), n(0), metrics(Metrics()), fitted(false) {}
|
BaseClassifier::BaseClassifier(Network model) : model(model), m(0), n(0), metrics(Metrics()), fitted(false) {}
|
||||||
BaseClassifier& BaseClassifier::build(vector<string>& features, string className, map<string, vector<int>>& states)
|
BaseClassifier& BaseClassifier::build(vector<string>& features, string className, map<string, vector<int>>& states)
|
||||||
{
|
{
|
||||||
|
|
||||||
dataset = torch::cat({ X, y.view({y.size(0), 1}) }, 1);
|
dataset = torch::cat({ X, y.view({y.size(0), 1}) }, 1);
|
||||||
this->features = features;
|
this->features = features;
|
||||||
this->className = className;
|
this->className = className;
|
||||||
@ -116,4 +115,13 @@ namespace bayesnet {
|
|||||||
}
|
}
|
||||||
model.addNode(className, states[className].size());
|
model.addNode(className, states[className].size());
|
||||||
}
|
}
|
||||||
|
int BaseClassifier::getNumberOfNodes()
|
||||||
|
{
|
||||||
|
// Features does not include class
|
||||||
|
return fitted ? model.getFeatures().size() + 1 : 0;
|
||||||
|
}
|
||||||
|
int BaseClassifier::getNumberOfEdges()
|
||||||
|
{
|
||||||
|
return fitted ? model.getEdges().size() : 0;
|
||||||
|
}
|
||||||
}
|
}
|
@ -30,6 +30,8 @@ namespace bayesnet {
|
|||||||
virtual ~BaseClassifier() = default;
|
virtual ~BaseClassifier() = default;
|
||||||
BaseClassifier& fit(vector<vector<int>>& X, vector<int>& y, vector<string>& features, string className, map<string, vector<int>>& states);
|
BaseClassifier& fit(vector<vector<int>>& X, vector<int>& y, vector<string>& features, string className, map<string, vector<int>>& states);
|
||||||
void addNodes();
|
void addNodes();
|
||||||
|
int getNumberOfNodes();
|
||||||
|
int getNumberOfEdges();
|
||||||
Tensor predict(Tensor& X);
|
Tensor predict(Tensor& X);
|
||||||
vector<int> predict(vector<vector<int>>& X);
|
vector<int> predict(vector<vector<int>>& X);
|
||||||
float score(Tensor& X, Tensor& y);
|
float score(Tensor& X, Tensor& y);
|
||||||
|
@ -275,5 +275,17 @@ namespace bayesnet {
|
|||||||
output.push_back("}\n");
|
output.push_back("}\n");
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
vector<pair<string, string>> Network::getEdges()
|
||||||
|
{
|
||||||
|
auto edges = vector<pair<string, string>>();
|
||||||
|
for (const auto& node : nodes) {
|
||||||
|
auto head = node.first;
|
||||||
|
for (const auto& child : node.second->getChildren()) {
|
||||||
|
auto tail = child->getName();
|
||||||
|
edges.push_back({ head, tail });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ namespace bayesnet {
|
|||||||
map<string, std::unique_ptr<Node>>& getNodes();
|
map<string, std::unique_ptr<Node>>& getNodes();
|
||||||
vector<string> getFeatures();
|
vector<string> getFeatures();
|
||||||
int getStates();
|
int getStates();
|
||||||
|
vector<pair<string, string>> getEdges();
|
||||||
int getClassNumStates();
|
int getClassNumStates();
|
||||||
string getClassName();
|
string getClassName();
|
||||||
void fit(const vector<vector<int>>&, const vector<int>&, const vector<string>&, const string&);
|
void fit(const vector<vector<int>>&, const vector<int>&, const vector<string>&, const string&);
|
||||||
|
@ -60,3 +60,29 @@ TEST_CASE("Test Bayesian Classifiers score", "[BayesNet]")
|
|||||||
// cout << "{{\"" << scores.first.first << "\", \"" << scores.first.second << "\"}, " << scores.second << "}, ";
|
// cout << "{{\"" << scores.first.first << "\", \"" << scores.first.second << "\"}, " << scores.second << "}, ";
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
TEST_CASE("Models features")
|
||||||
|
{
|
||||||
|
auto graph = vector<string>({ "digraph BayesNet {\nlabel=<BayesNet Test>\nfontsize=30\nfontcolor=blue\nlabelloc=t\nlayout=circo\n",
|
||||||
|
"class [shape=circle, fontcolor=red, fillcolor=lightblue, style=filled ] \n",
|
||||||
|
"class -> sepallength", "class -> sepalwidth", "class -> petallength", "class -> petalwidth", "petallength [shape=circle] \n",
|
||||||
|
"petallength -> sepallength", "petalwidth [shape=circle] \n", "sepallength [shape=circle] \n",
|
||||||
|
"sepallength -> sepalwidth", "sepalwidth [shape=circle] \n", "sepalwidth -> petalwidth", "}\n"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
auto clf = bayesnet::TAN();
|
||||||
|
auto [Xd, y, features, className, states] = loadFile("iris");
|
||||||
|
clf.fit(Xd, y, features, className, states);
|
||||||
|
REQUIRE(clf.getNumberOfNodes() == 5);
|
||||||
|
REQUIRE(clf.getNumberOfEdges() == 7);
|
||||||
|
REQUIRE(clf.show() == vector<string>{"class -> sepallength, sepalwidth, petallength, petalwidth, ", "petallength -> sepallength, ", "petalwidth -> ", "sepallength -> sepalwidth, ", "sepalwidth -> petalwidth, "});
|
||||||
|
REQUIRE(clf.graph("Test") == graph);
|
||||||
|
}
|
||||||
|
TEST_CASE("Get num features & num edges")
|
||||||
|
{
|
||||||
|
auto [Xd, y, features, className, states] = loadFile("iris");
|
||||||
|
auto clf = bayesnet::KDB(2);
|
||||||
|
clf.fit(Xd, y, features, className, states);
|
||||||
|
REQUIRE(clf.getNumberOfNodes() == 5);
|
||||||
|
REQUIRE(clf.getNumberOfEdges() == 8);
|
||||||
|
}
|
@ -26,4 +26,16 @@ TEST_CASE("Test Bayesian Network")
|
|||||||
net.addNode("C", 2);
|
net.addNode("C", 2);
|
||||||
REQUIRE(net.getFeatures() == vector<string>{"A", "B", "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.addEdge("A", "B");
|
||||||
|
net.addEdge("B", "C");
|
||||||
|
REQUIRE(net.getEdges() == vector<pair<string, string>>{ {"A", "B"}, { "B", "C" } });
|
||||||
|
net.addEdge("A", "C");
|
||||||
|
REQUIRE(net.getEdges() == vector<pair<string, string>>{ {"A", "B"}, { "A", "C" }, { "B", "C" } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
if(ENABLE_TESTING)
|
if(ENABLE_TESTING)
|
||||||
set(TEST_MAIN "unit_tests")
|
set(TEST_MAIN "unit_tests")
|
||||||
set(TEST_SOURCES main.cc ../sample/ArffFiles.cc ../sample/CPPFImdlp.cpp ../sample/Metrics.cpp
|
set(TEST_SOURCES BayesModels.cc BayesNetwork.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/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 BayesNetwork.cc utils.cc utils.h)
|
../src/TAN.cc ../src/SPODE.cc ../src/Ensemble.cc ../src/AODE.cc ../src/Mst.cc utils.cc utils.h)
|
||||||
add_executable(${TEST_MAIN} ${TEST_SOURCES})
|
add_executable(${TEST_MAIN} ${TEST_SOURCES})
|
||||||
target_link_libraries(${TEST_MAIN} PUBLIC "${TORCH_LIBRARIES}" Catch2::Catch2WithMain)
|
target_link_libraries(${TEST_MAIN} PUBLIC "${TORCH_LIBRARIES}" Catch2::Catch2WithMain)
|
||||||
add_test(NAME ${TEST_MAIN} COMMAND ${TEST_MAIN})
|
add_test(NAME ${TEST_MAIN} COMMAND ${TEST_MAIN})
|
||||||
|
Loading…
Reference in New Issue
Block a user