Fix json key automatic ordering error when creating Score from json
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
namespace platform {
|
||||
class BestResults {
|
||||
public:
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "reports/ExcelFile.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
namespace platform {
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
namespace platform {
|
||||
struct WTL {
|
||||
|
@@ -13,7 +13,7 @@
|
||||
#include "grid/GridSearch.h"
|
||||
#include "config.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
const int MAXL = 133;
|
||||
|
||||
void assignModel(argparse::ArgumentParser& parser)
|
||||
@@ -29,7 +29,7 @@ void assignModel(argparse::ArgumentParser& parser)
|
||||
}
|
||||
throw std::runtime_error("Model must be one of " + models->toString());
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
void add_compute_args(argparse::ArgumentParser& program)
|
||||
{
|
||||
@@ -54,23 +54,23 @@ void add_compute_args(argparse::ArgumentParser& program)
|
||||
catch (...) {
|
||||
throw std::runtime_error("Number of nested folds must be an integer");
|
||||
}});
|
||||
program.add_argument("--score").help("Score used in gridsearch").default_value("accuracy");
|
||||
program.add_argument("-f", "--folds").help("Number of folds").default_value(stoi(env.get("n_folds"))).scan<'i', int>().action([](const std::string& value) {
|
||||
try {
|
||||
auto k = stoi(value);
|
||||
if (k < 2) {
|
||||
throw std::runtime_error("Number of folds must be greater than 1");
|
||||
program.add_argument("--score").help("Score used in gridsearch").default_value("accuracy");
|
||||
program.add_argument("-f", "--folds").help("Number of folds").default_value(stoi(env.get("n_folds"))).scan<'i', int>().action([](const std::string& value) {
|
||||
try {
|
||||
auto k = stoi(value);
|
||||
if (k < 2) {
|
||||
throw std::runtime_error("Number of folds must be greater than 1");
|
||||
}
|
||||
return k;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
catch (const runtime_error& err) {
|
||||
throw std::runtime_error(err.what());
|
||||
}
|
||||
catch (...) {
|
||||
throw std::runtime_error("Number of folds must be an integer");
|
||||
}});
|
||||
auto seed_values = env.getSeeds();
|
||||
program.add_argument("-s", "--seeds").nargs(1, 10).help("Random seeds. Set to -1 to have pseudo random").scan<'i', int>().default_value(seed_values);
|
||||
catch (const runtime_error& err) {
|
||||
throw std::runtime_error(err.what());
|
||||
}
|
||||
catch (...) {
|
||||
throw std::runtime_error("Number of folds must be an integer");
|
||||
}});
|
||||
auto seed_values = env.getSeeds();
|
||||
program.add_argument("-s", "--seeds").nargs(1, 10).help("Random seeds. Set to -1 to have pseudo random").scan<'i', int>().default_value(seed_values);
|
||||
}
|
||||
std::string headerLine(const std::string& text, int utf = 0)
|
||||
{
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "config.h"
|
||||
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
void manageArguments(argparse::ArgumentParser& program)
|
||||
{
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
const std::string ALL_DATASETS = "all";
|
||||
class GridData {
|
||||
public:
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "GridData.h"
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
struct ConfigGrid {
|
||||
std::string model;
|
||||
std::string score;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "Scores.h"
|
||||
#include "Experiment.h"
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
void Experiment::saveResult()
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#include "results/Result.h"
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
class Experiment {
|
||||
public:
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
class HyperParameters {
|
||||
public:
|
||||
HyperParameters() = default;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
class PartialResult {
|
||||
|
||||
public:
|
||||
|
@@ -37,11 +37,16 @@ namespace platform {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Compute accuracy with the confusion matrix
|
||||
compute_accuracy_value();
|
||||
}
|
||||
void Scores::compute_accuracy_value()
|
||||
{
|
||||
accuracy_value = 0;
|
||||
for (int i = 0; i < num_classes; i++) {
|
||||
accuracy_value += confusion_matrix[i][i].item<int>();
|
||||
}
|
||||
accuracy_value /= total;
|
||||
accuracy_value = std::min(accuracy_value, 1.0f);
|
||||
}
|
||||
void Scores::init_confusion_matrix()
|
||||
{
|
||||
@@ -59,8 +64,7 @@ namespace platform {
|
||||
throw std::invalid_argument("The number of classes must be the same");
|
||||
confusion_matrix += a.confusion_matrix;
|
||||
total += a.total;
|
||||
accuracy_value += a.accuracy_value;
|
||||
accuracy_value /= 2;
|
||||
compute_accuracy_value();
|
||||
}
|
||||
float Scores::accuracy()
|
||||
{
|
||||
@@ -71,6 +75,7 @@ namespace platform {
|
||||
// Compute f1_score in a one vs rest fashion
|
||||
auto precision_value = precision(num_class);
|
||||
auto recall_value = recall(num_class);
|
||||
if (precision_value + recall_value == 0) return 0; // Avoid division by zero (0/0 = 0)
|
||||
return 2 * precision_value * recall_value / (precision_value + recall_value);
|
||||
}
|
||||
float Scores::f1_weighted()
|
||||
@@ -94,6 +99,7 @@ namespace platform {
|
||||
int tp = confusion_matrix[num_class][num_class].item<int>();
|
||||
int fp = confusion_matrix.index({ "...", num_class }).sum().item<int>() - tp;
|
||||
int fn = confusion_matrix[num_class].sum().item<int>() - tp;
|
||||
if (tp + fp == 0) return 0; // Avoid division by zero (0/0 = 0
|
||||
return float(tp) / (tp + fp);
|
||||
}
|
||||
float Scores::recall(int num_class)
|
||||
@@ -101,6 +107,7 @@ namespace platform {
|
||||
int tp = confusion_matrix[num_class][num_class].item<int>();
|
||||
int fp = confusion_matrix.index({ "...", num_class }).sum().item<int>() - tp;
|
||||
int fn = confusion_matrix[num_class].sum().item<int>() - tp;
|
||||
if (tp + fn == 0) return 0; // Avoid division by zero (0/0 = 0
|
||||
return float(tp) / (tp + fn);
|
||||
}
|
||||
std::string Scores::classification_report_line(std::string label, float precision, float recall, float f1_score, int support)
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <torch/torch.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
class Scores {
|
||||
public:
|
||||
Scores(torch::Tensor& y_test, torch::Tensor& y_pred, int num_classes, std::vector<std::string> labels = {});
|
||||
@@ -24,6 +24,7 @@ namespace platform {
|
||||
std::string classification_report_line(std::string label, float precision, float recall, float f1_score, int support);
|
||||
void init_confusion_matrix();
|
||||
void init_default_labels();
|
||||
void compute_accuracy_value();
|
||||
int num_classes;
|
||||
float accuracy_value;
|
||||
int total;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "results/Result.h"
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
enum class SortType {
|
||||
ASC = 0,
|
||||
DESC = 1,
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include "ReportsPaged.h"
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
|
||||
class DatasetsConsole : public ReportsPaged {
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "reports/ExcelFile.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
namespace platform {
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include "common/Paths.h"
|
||||
#include "common/Symbols.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
namespace platform {
|
||||
|
||||
class ReportBase {
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
class ReportsPaged {
|
||||
public:
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#include "main/PartialResult.h"
|
||||
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
class Result {
|
||||
public:
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "results/Result.h"
|
||||
namespace platform {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
class ResultsDataset {
|
||||
public:
|
||||
ResultsDataset(const std::string& dataset, const std::string& model, const std::string& score);
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "reports/ExcelFile.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::ordered_json;
|
||||
|
||||
namespace platform {
|
||||
|
||||
|
@@ -19,12 +19,12 @@ TEST_CASE("Test Platform version", "[Platform]")
|
||||
TEST_CASE("Test Folding library version", "[Folding]")
|
||||
{
|
||||
std::string version = folding::KFold(5, 100).version();
|
||||
REQUIRE(version == "1.0.1");
|
||||
REQUIRE(version == "1.1.0");
|
||||
}
|
||||
TEST_CASE("Test BayesNet version", "[BayesNet]")
|
||||
{
|
||||
std::string version = bayesnet::TAN().getVersion();
|
||||
REQUIRE(version == "1.0.4.1");
|
||||
REQUIRE(version == "1.0.5.1");
|
||||
}
|
||||
TEST_CASE("Test mdlp version", "[mdlp]")
|
||||
{
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "main/Scores.h"
|
||||
#include "config.h"
|
||||
|
||||
using json = nlohmann::ordered_json;
|
||||
auto epsilon = 1e-4;
|
||||
|
||||
void make_test_bin(int TP, int TN, int FP, int FN, std::vector<int>& y_test, std::vector<int>& y_pred)
|
||||
@@ -157,7 +158,7 @@ TEST_CASE("JSON constructor", "[Scores]")
|
||||
std::vector<int> y_pred = { 0, 1, 2, 2, 1, 1, 1, 0, 0, 2 };
|
||||
auto y_test_tensor = torch::tensor(y_test, torch::kInt32);
|
||||
auto y_pred_tensor = torch::tensor(y_pred, torch::kInt32);
|
||||
std::vector<std::string> labels = { "Aeroplane", "Boat", "Car" };
|
||||
std::vector<std::string> labels = { "Car", "Boat", "Aeroplane" };
|
||||
platform::Scores scores(y_test_tensor, y_pred_tensor, 3, labels);
|
||||
auto res_json_int = scores.get_confusion_matrix_json();
|
||||
platform::Scores scores2(res_json_int);
|
||||
@@ -218,4 +219,33 @@ TEST_CASE("Aggregate", "[Scores]")
|
||||
REQUIRE(scores3.f1_weighted() == scores.f1_weighted());
|
||||
REQUIRE(scores3.f1_macro() == scores.f1_macro());
|
||||
REQUIRE(scores3.accuracy() == scores.accuracy());
|
||||
}
|
||||
TEST_CASE("Order of keys", "[Scores]")
|
||||
{
|
||||
std::vector<int> y_test = { 0, 2, 2, 2, 2, 0, 1, 2, 0, 2 };
|
||||
std::vector<int> y_pred = { 0, 1, 2, 2, 1, 1, 1, 0, 0, 2 };
|
||||
auto y_test_tensor = torch::tensor(y_test, torch::kInt32);
|
||||
auto y_pred_tensor = torch::tensor(y_pred, torch::kInt32);
|
||||
std::vector<std::string> labels = { "Car", "Boat", "Aeroplane" };
|
||||
platform::Scores scores(y_test_tensor, y_pred_tensor, 3, labels);
|
||||
auto res_json_int = scores.get_confusion_matrix_json(true);
|
||||
// Make a temp file and store the json
|
||||
std::string filename = "temp.json";
|
||||
std::ofstream file(filename);
|
||||
file << res_json_int;
|
||||
file.close();
|
||||
// Read the json from the file
|
||||
std::ifstream file2(filename);
|
||||
json res_json_int2;
|
||||
file2 >> res_json_int2;
|
||||
file2.close();
|
||||
// Remove the temp file
|
||||
std::remove(filename.c_str());
|
||||
platform::Scores scores2(res_json_int2);
|
||||
REQUIRE(scores.accuracy() == scores2.accuracy());
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
REQUIRE(scores.f1_score(i) == scores2.f1_score(i));
|
||||
REQUIRE(scores.precision(i) == scores2.precision(i));
|
||||
REQUIRE(scores.recall(i) == scores2.recall(i));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user