Complete Excel Report with data

This commit is contained in:
Ricardo Montañana Gómez 2023-08-22 11:55:15 +02:00
parent d2da0ddb88
commit c59dd30e53
Signed by: rmontanana
GPG Key ID: 46064262FD9A7ADE
7 changed files with 85 additions and 53 deletions

View File

@ -6,6 +6,7 @@ namespace platform {
public: public:
static std::string datasets() { return "datasets/"; } static std::string datasets() { return "datasets/"; }
static std::string results() { return "results/"; } static std::string results() { return "results/"; }
static std::string excel() { return "excel/"; }
}; };
} }
#endif #endif

View File

@ -33,6 +33,5 @@ namespace platform {
{ {
header(); header();
body(); body();
footer();
} }
} }

View File

@ -14,12 +14,10 @@ namespace platform {
void show(); void show();
protected: protected:
json data; json data;
double totalScore; // Total score of all results in a report
string fromVector(const string& key); string fromVector(const string& key);
string fVector(const string& title, const json& data, const int width, const int precision); string fVector(const string& title, const json& data, const int width, const int precision);
virtual void header() = 0; virtual void header() = 0;
virtual void body() = 0; virtual void body() = 0;
virtual void footer() = 0;
}; };
}; };
#endif #endif

View File

@ -10,6 +10,7 @@ namespace platform {
char do_thousands_sep() const { return '.'; } char do_thousands_sep() const { return '.'; }
string do_grouping() const { return "\03"; } string do_grouping() const { return "\03"; }
}; };
string ReportConsole::headerLine(const string& text) string ReportConsole::headerLine(const string& text)
{ {
int n = MAXL - text.length() - 3; int n = MAXL - text.length() - 3;
@ -38,7 +39,7 @@ namespace platform {
cout << Colors::GREEN() << "Dataset Sampl. Feat. Cls Nodes Edges States Score Time Hyperparameters" << endl; cout << Colors::GREEN() << "Dataset Sampl. Feat. Cls Nodes Edges States Score Time Hyperparameters" << endl;
cout << "============================== ====== ===== === ========= ========= ========= =============== ================== ===============" << endl; cout << "============================== ====== ===== === ========= ========= ========= =============== ================== ===============" << endl;
json lastResult; json lastResult;
totalScore = 0; double totalScore = 0.0;
bool odd = true; bool odd = true;
for (const auto& r : data["results"]) { for (const auto& r : data["results"]) {
auto color = odd ? Colors::CYAN() : Colors::BLUE(); auto color = odd ? Colors::CYAN() : Colors::BLUE();
@ -69,9 +70,11 @@ namespace platform {
cout << headerLine(fVector("Train times: ", lastResult["times_train"], 10, 3)); cout << headerLine(fVector("Train times: ", lastResult["times_train"], 10, 3));
cout << headerLine(fVector("Test times: ", lastResult["times_test"], 10, 3)); cout << headerLine(fVector("Test times: ", lastResult["times_test"], 10, 3));
cout << string(MAXL, '*') << endl; cout << string(MAXL, '*') << endl;
} else {
footer(totalScore);
} }
} }
void ReportConsole::footer() void ReportConsole::footer(double totalScore)
{ {
cout << Colors::MAGENTA() << string(MAXL, '*') << endl; cout << Colors::MAGENTA() << string(MAXL, '*') << endl;
auto score = data["score_name"].get<string>(); auto score = data["score_name"].get<string>();

View File

@ -16,7 +16,7 @@ namespace platform {
string headerLine(const string& text); string headerLine(const string& text);
void header() override; void header() override;
void body() override; void body() override;
void footer() override; void footer(double totalScore);
}; };
}; };
#endif #endif

View File

@ -7,79 +7,103 @@
namespace platform { namespace platform {
struct separated : numpunct<char> { struct separated : numpunct<char> {
char do_decimal_point() const { return ','; } char do_decimal_point() const { return ','; }
char do_thousands_sep() const { return '.'; } char do_thousands_sep() const { return '.'; }
string do_grouping() const { return "\03"; } string do_grouping() const { return "\03"; }
}; };
string headerLine(const string& text)
void ReportExcel::createFile()
{ {
int n = MAXLL - text.length() - 3; doc.create(Paths::excel() + "some_results.xlsx");
n = n < 0 ? 0 : n; wks = doc.workbook().worksheet("Sheet1");
return "* " + text + string(n, ' ') + "*\n"; wks.setName(data["model"].get<string>());
} }
void ReportExcel::closeFile()
{
doc.save();
doc.close();
}
void ReportExcel::header() void ReportExcel::header()
{ {
locale mylocale(cout.getloc(), new separated); locale mylocale(cout.getloc(), new separated);
locale::global(mylocale); locale::global(mylocale);
cout.imbue(mylocale); cout.imbue(mylocale);
stringstream oss; stringstream oss;
cout << Colors::MAGENTA() << string(MAXLL, '*') << endl; wks.cell("A1").value().set(
cout << headerLine("Report " + data["model"].get<string>() + " ver. " + data["version"].get<string>() + " with " + to_string(data["folds"].get<int>()) + " Folds cross validation and " + to_string(data["seeds"].size()) + " random seeds. " + data["date"].get<string>() + " " + data["time"].get<string>()); "Report " + data["model"].get<string>() + " ver. " + data["version"].get<string>() + " with " +
cout << headerLine(data["title"].get<string>()); to_string(data["folds"].get<int>()) + " Folds cross validation and " + to_string(data["seeds"].size()) +
cout << headerLine("Random seeds: " + fromVector("seeds") + " Stratified: " + (data["stratified"].get<bool>() ? "True" : "False")); " random seeds. " + data["date"].get<string>() + " " + data["time"].get<string>());
oss << "Execution took " << setprecision(2) << fixed << data["duration"].get<float>() << " seconds, " << data["duration"].get<float>() / 3600 << " hours, on " << data["platform"].get<string>(); wks.cell("A2").value() = data["title"].get<string>();
cout << headerLine(oss.str()); wks.cell("A3").value() = "Random seeds: " + fromVector("seeds") + " Stratified: " +
cout << headerLine("Score is " + data["score_name"].get<string>()); (data["stratified"].get<bool>() ? "True" : "False");
cout << string(MAXLL, '*') << endl; oss << "Execution took " << setprecision(2) << fixed << data["duration"].get<float>() << " seconds, "
cout << endl; << data["duration"].get<float>() / 3600 << " hours, on " << data["platform"].get<string>();
wks.cell("A4").value() = oss.str();
wks.cell("A5").value() = "Score is " + data["score_name"].get<string>();
} }
void ReportExcel::body() void ReportExcel::body()
{ {
cout << Colors::GREEN() << "Dataset Sampl. Feat. Cls Nodes Edges States Score Time Hyperparameters" << endl; auto header = vector<string>(
cout << "============================== ====== ===== === ========= ========= ========= =============== ================== ===============" << endl; { "Dataset", "Samples", "Features", "Classes", "Nodes", "Edges", "States", "Score", "Score Std.", "Time",
"Time Std.", "Hyperparameters" });
int col = 1;
for (const auto& item : header) {
wks.cell(8, col++).value() = item;
}
int row = 9;
col = 1;
json lastResult; json lastResult;
totalScore = 0; double totalScore = 0.0;
bool odd = true; string hyperparameters;
for (const auto& r : data["results"]) { for (const auto& r : data["results"]) {
auto color = odd ? Colors::CYAN() : Colors::BLUE(); wks.cell(row, col).value() = r["dataset"].get<string>();
cout << color << setw(30) << left << r["dataset"].get<string>() << " "; wks.cell(row, col + 1).value() = r["samples"].get<int>();
cout << setw(6) << right << r["samples"].get<int>() << " "; wks.cell(row, col + 2).value() = r["features"].get<int>();
cout << setw(5) << right << r["features"].get<int>() << " "; wks.cell(row, col + 3).value() = r["classes"].get<int>();
cout << setw(3) << right << r["classes"].get<int>() << " "; wks.cell(row, col + 4).value() = r["nodes"].get<float>();
cout << setw(9) << setprecision(2) << fixed << r["nodes"].get<float>() << " "; wks.cell(row, col + 5).value() = r["leaves"].get<float>();
cout << setw(9) << setprecision(2) << fixed << r["leaves"].get<float>() << " "; wks.cell(row, col + 6).value() = r["depth"].get<float>();
cout << setw(9) << setprecision(2) << fixed << r["depth"].get<float>() << " "; wks.cell(row, col + 7).value() = r["score"].get<double>();
cout << setw(8) << right << setprecision(6) << fixed << r["score"].get<double>() << "±" << setw(6) << setprecision(4) << fixed << r["score_std"].get<double>() << " "; wks.cell(row, col + 8).value() = r["score_std"].get<double>();
cout << setw(11) << right << setprecision(6) << fixed << r["time"].get<double>() << "±" << setw(6) << setprecision(4) << fixed << r["time_std"].get<double>() << " "; wks.cell(row, col + 9).value() = r["time"].get<double>();
wks.cell(row, col + 10).value() = r["time_std"].get<double>();
try { try {
cout << r["hyperparameters"].get<string>(); hyperparameters = r["hyperparameters"].get<string>();
} }
catch (const exception& err) { catch (const exception& err) {
cout << r["hyperparameters"]; stringstream oss;
oss << r["hyperparameters"];
hyperparameters = oss.str();
} }
cout << endl; wks.cell(row, col + 11).value() = hyperparameters;
lastResult = r; lastResult = r;
totalScore += r["score"].get<double>(); totalScore += r["score"].get<double>();
odd = !odd; row++;
} }
if (data["results"].size() == 1) { if (data["results"].size() == 1) {
cout << string(MAXLL, '*') << endl; for (const string& group : { "scores_train", "scores_test", "times_train", "times_test" }) {
cout << headerLine(fVector("Train scores: ", lastResult["scores_train"], 14, 12)); row++;
cout << headerLine(fVector("Test scores: ", lastResult["scores_test"], 14, 12)); col = 1;
cout << headerLine(fVector("Train times: ", lastResult["times_train"], 10, 3)); wks.cell(row, col).value() = group;
cout << headerLine(fVector("Test times: ", lastResult["times_test"], 10, 3)); for (double item : lastResult[group]) {
cout << string(MAXLL, '*') << endl; wks.cell(row, ++col).value() = item;
}
}
} else {
footer(totalScore, row);
} }
} }
void ReportExcel::footer()
void ReportExcel::footer(double totalScore, int row)
{ {
cout << Colors::MAGENTA() << string(MAXLL, '*') << endl;
auto score = data["score_name"].get<string>(); auto score = data["score_name"].get<string>();
if (score == BestResult::scoreName()) { if (score == BestResult::scoreName()) {
stringstream oss; wks.cell(row + 2, 1).value() = score + " compared to " + BestResult::title() + " .: ";
oss << score << " compared to " << BestResult::title() << " .: " << totalScore / BestResult::score(); wks.cell(row + 2, 5).value() = totalScore / BestResult::score();
cout << headerLine(oss.str());
} }
cout << string(MAXLL, '*') << endl << Colors::RESET();
} }
} }

View File

@ -1,18 +1,25 @@
#ifndef REPORTEXCEL_H #ifndef REPORTEXCEL_H
#define REPORTEXCEL_H #define REPORTEXCEL_H
#include <OpenXLSX.hpp>
#include "ReportBase.h" #include "ReportBase.h"
#include "Paths.h"
#include "Colors.h" #include "Colors.h"
namespace platform { namespace platform {
using namespace std; using namespace std;
using namespace OpenXLSX;
const int MAXLL = 128; const int MAXLL = 128;
class ReportExcel : public ReportBase{ class ReportExcel : public ReportBase{
public: public:
explicit ReportExcel(json data_) : ReportBase(data_) {}; explicit ReportExcel(json data_) : ReportBase(data_) {createFile();};
virtual ~ReportExcel() = default; virtual ~ReportExcel() {closeFile();};
private: private:
void createFile();
void closeFile();
XLDocument doc;
XLWorksheet wks;
void header() override; void header() override;
void body() override; void body() override;
void footer() override; void footer(double totalScore, int row);
}; };
}; };
#endif // !REPORTEXCEL_H #endif // !REPORTEXCEL_H