Skip to content

Commit

Permalink
major update
Browse files Browse the repository at this point in the history
  • Loading branch information
ksiminski committed Apr 23, 2024
1 parent 3c15e38 commit bfb9377
Show file tree
Hide file tree
Showing 58 changed files with 2,412 additions and 1,155 deletions.
82 changes: 59 additions & 23 deletions source/auxiliary/confusion-matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,26 @@
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>

#include "../auxiliary/confusion-matrix.h"
#include "../auxiliary/mathematics.h"
#include "../service/debug.h"
#include "../common/result.h"

double ksi::confusion_matrix::TrainF1score (const ksi::result & r)
{
double recall = 1.0 * (r.TrainPositive2Positive) / (r.TrainPositive2Positive + r.TrainPositive2Negative);
double precision = 1.0 * (r.TrainPositive2Positive) / (r.TrainPositive2Positive + r.TrainNegative2Positive);
return (2.0 * recall * precision) / (recall + precision);
}

double ksi::confusion_matrix::TestF1score (const ksi::result & r)
{
double recall = 1.0 * (r.TestPositive2Positive) / (r.TestPositive2Positive + r.TestPositive2Negative);
double precision = 1.0 * (r.TestPositive2Positive) / (r.TestPositive2Positive + r.TestNegative2Positive);
return (2.0 * recall * precision) / (recall + precision);
}


std::string ksi::confusion_matrix::ca(int n)
Expand Down Expand Up @@ -157,20 +173,38 @@ void ksi::confusion_matrix::calculate_statistics (
}
}

std::string ksi::confusion_matrix::print(const ksi::result results, const bool print_for_test)
{
if (print_for_test)
return ksi::confusion_matrix::print(results.TestPositive2Positive, results.TestNegative2Negative, results.TestNegative2Positive, results.TestPositive2Negative);
else
return ksi::confusion_matrix::print(results.TrainPositive2Positive, results.TrainNegative2Negative, results.TrainNegative2Positive, results.TrainPositive2Negative);
}

double ksi::confusion_matrix::safe_division(const double number, const double divisor)
{
if (divisor == 0)
return std::numeric_limits<double>::quiet_NaN();
else
return number / divisor;
}

double ksi::confusion_matrix::safe(const double d)
{
return d != 0 ? d : std::numeric_limits<double>::quiet_NaN();
}

std::string ksi::confusion_matrix::print(
int nTruePositives,
int nTrueNegatives,
int nFalsePositives,
int nFalseNegatives)
{

std::stringstream ss;


int CP; // conditional (original) positives
int CN; // conditional (original) negatives
int OP; // TestOutcomePositives
int OP; // TestOutcomePositives
int ON; // TestOutcomeNegatives;
int To; // TotalPopulation

Expand All @@ -186,34 +220,36 @@ std::string ksi::confusion_matrix::print(
int TN = nTrueNegatives;
int FP = nFalsePositives;
int FN = nFalseNegatives;


double PRE, PPV, FDR, FOR, NPV, LRP, TPR, FPR, ACC, FNR, TNR, DOR, LRN, F1S, BA, TS, NA, FM, dP, BM, MCC, PT, P4;

PRE = (double) CP / To;
PPV = (double) nTruePositives / OP;
FDR = (double) nFalsePositives / OP;
FOR = (double) nFalseNegatives / ON;
NPV = (double) nTrueNegatives / ON;
TPR = (double) nTruePositives / CP;
FNR = (double) nFalsePositives / CP;
FPR = (double) nFalsePositives / CN;
TNR = (double) nTrueNegatives / CN;
ACC = (double) (nTruePositives + nTrueNegatives) / To;
PRE = (double) CP / ksi::confusion_matrix::safe(To);
PPV = (double) nTruePositives / ksi::confusion_matrix::safe(OP);
FDR = (double) nFalsePositives / ksi::confusion_matrix::safe(OP);
FOR = (double) nFalseNegatives / ksi::confusion_matrix::safe(ON);
NPV = (double) nTrueNegatives / ksi::confusion_matrix::safe(ON);
TPR = (double) nTruePositives / ksi::confusion_matrix::safe(CP);
FNR = (double) nFalsePositives / ksi::confusion_matrix::safe(CP);
FPR = (double) nFalsePositives / ksi::confusion_matrix::safe(CN);
TNR = (double) nTrueNegatives / ksi::confusion_matrix::safe(CN);
ACC = (double) (nTruePositives + nTrueNegatives) / ksi::confusion_matrix::safe(To);

F1S = 2 * TPR * PPV / (TPR + PPV);
LRP = TPR / FPR;
LRN = FNR / TNR;
DOR = LRP / LRN;
F1S = 2 * TPR * PPV / ksi::confusion_matrix::safe((TPR + PPV));
LRP = TPR / ksi::confusion_matrix::safe(FPR);
LRN = FNR / ksi::confusion_matrix::safe(TNR);
DOR = LRP / ksi::confusion_matrix::safe(LRN);

TS = TP / (TP + FN + FP);
TS = TP / ksi::confusion_matrix::safe((TP + FN + FP));
BA = (TPR + TNR) / 2.0;
FM = sqrt(PPV * TPR);
dP = PPV + NPV - 1;
BM = TPR + TNR - 1;
MCC = (TP * TN - FP * FN) / (sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN)));
PT = (sqrt(TPR * FPR) - FPR) / (TPR - FPR);
P4 = (4 * TP * TN) / (4 * TP * TN + (TP + TN)*(FP + FN));
MCC = (TP * TN - FP * FN) / ksi::confusion_matrix::safe((sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN))));
PT = (sqrt(TPR * FPR) - FPR) / ksi::confusion_matrix::safe((TPR - FPR));
if ((4 * TP * TN + (TP + TN)*(FP + FN)) == 0)
P4 = std::numeric_limits<double>::quiet_NaN();
else
P4 = (4 * TP * TN) / (4 * TP * TN + (TP + TN)*(FP + FN));

ss <<
"+------------------+------------------+--------------------+-----------------------+---------------------+" << std::endl <<
Expand Down Expand Up @@ -306,7 +342,7 @@ std::string ksi::confusion_matrix::print(
ss << "Positive likelihood ratio (LR+) = TPR / FPR: " << ul(LRP) << std::endl;
ss << "Negative likelihood ratio (LR−) = FNR / TNR: " << ul(LRN) << std::endl;
ss << "Diagnostic odds ratio (DOR) = LR+ / LR−: " << ul(DOR) << std::endl;
ss << "F1 score = recall * precision / (recall + precision): " << ul(F1S) << std::endl;
ss << "F1 score = 2 * recall * precision / (recall + precision): " << ul(F1S) << std::endl;
ss << "Threat score (TS, critical success index CSI, Jaccard index) = TP / (TP + FN + FP): " << ul(TS) << std::endl;
ss << "Balanced accuracy (BA) = (TPR + TNR) / 2 : " << ul(BA) << std::endl;
ss << "Fowlkes–Mallows index (FM) = sqrt(PPV * TPR): " << ul(FM) << std::endl;
Expand Down
30 changes: 30 additions & 0 deletions source/auxiliary/confusion-matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <vector>
#include <string>

#include "../common/result.h"

namespace ksi
{
/** This class calculates statistics and prints confusion matrix. */
Expand Down Expand Up @@ -66,6 +68,13 @@ namespace ksi
int nFalsePositives,
int nFalseNegatives);

/** The method prints values of a confusion matrix. It prints all values and a nice matrix.
* @param results
* @param print_for_test if true, the method print a confusion matrix for test data, otherwise -- for train data.
* @date 2024-03-12
*/
std::string print (const ksi::result results, const bool print_for_test = true);

protected:
/** prints a double values with precision to fit the table */
std::string ul(double d);
Expand All @@ -75,6 +84,27 @@ namespace ksi
/** @return true if abs(left - right) < EPSILON
EPSILON = 0.0001 */
bool equal (const double left, const double right);

/** @return quiet_NaN if division impossible, otherwise a legal quotient
* @date 2024-04-01 */
double safe_division(const double number, const double divisor);

/** @return quiet_NaN if number is zero, otherwise the number itself
* @date 2024-04-01 */
double safe(const double number);

public:
/** @return f1-score for the test results
* @date 2024-03-28
* @author Krzysztof Siminski */
static double TestF1score (const ksi::result & r);

/** @return f1-score for the train results
* @date 2024-03-28
* @author Krzysztof Siminski */
static double TrainF1score (const ksi::result & r);


};

}
Expand Down
16 changes: 10 additions & 6 deletions source/auxiliary/directory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@

bool ksi::directory::create_directory_for_file(const std::string & file_path)
{
std::filesystem::path sciezka_pliku (file_path);
auto sciezka_katalogu = sciezka_pliku.parent_path();
if (not std::filesystem::exists(sciezka_katalogu))
return std::filesystem::create_directories(sciezka_katalogu);
else
return true;
try
{
std::filesystem::path sciezka_pliku (file_path);
auto sciezka_katalogu = sciezka_pliku.parent_path();
if (not std::filesystem::exists(sciezka_katalogu))
return std::filesystem::create_directories(sciezka_katalogu);
else
return true;
}
CATCH;
}

25 changes: 11 additions & 14 deletions source/auxiliary/utility-math.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ namespace ksi
/** @return The function returns standard deviation and median of elements in a vector.
* @param first iterator to the first element
* @param last iterator to the past-the-end element in the vector
* @param k k-th smallest (starts with 0)
* @date 2023-11-21
* @author Konrad Wnuk
* @throw std::string if the array has no items
Expand Down Expand Up @@ -259,21 +258,21 @@ namespace ksi
* @brief Calculates the equation of a line given two points.
*
* This function calculates the equation of a line in the form \f$y = ax + b\f$,
* where \f$a\f$ is the slope and \f$b\f$ is the y-intercept, based on two given points.
* where \f$a\f$ is the slope and \f$b\f$ is the y-constant term, based on two given points.
*
* @tparam T The data type of the coordinates (default is double)
* @param p1 The first point \f$x, y\f$
* @param p2 The second point \f$x, y\f$
* @return A pair representing the slope and y-intercept of the line
* @return A pair representing the slope and y-constant term of the line
*
* The slope \f$a\f$ is calculated as:
* \f[
* \text{slope} = \frac{{y_2 - y_1}}{{x_2 - x_1}}
* a = \frac{{y_2 - y_1}}{{x_2 - x_1}}
* \f]
*
* The y-intercept \f$b\f$ is calculated as:
* The y-constant term \f$b\f$ is calculated as:
* \f[
* \text{intercept} = y_1 - \text{slope} \cdot x_1
* b = y_1 - \text{slope} \cdot x_1
* \f]
*
* @date 2023-12-26
Expand All @@ -283,9 +282,9 @@ namespace ksi
static
std::pair<T, T> calculateLineEquation(const std::pair<T, T>& p1, const std::pair<T, T>& p2) {
const double slope = (p2.second - p1.second) / (p2.first - p1.first);
const double intercept = p1.second - slope * p1.first;
const double constant_term = p1.second - slope * p1.first;

return std::make_pair(slope, intercept);
return std::make_pair(slope, constant_term);
}

/**
Expand All @@ -310,7 +309,7 @@ namespace ksi
T calculateLinearDefiniteIntegralValue(const T& x1, const T& x2, const std::pair<T, T>& params, const T& expected) {
auto f = [params] (const auto& x, const auto& expected)
{
return (params.first * pow(x, 4)) / 4 + (params.second * pow(x, 3) - 2 * expected * params.first * pow(x, 3)) / 3 - expected * params.second * pow(x, 2) + (pow(expected, 2) * params.first * pow(x, 2)) / 2 + pow(expected, 2) * params.second * x;
return (params.first * pow(x, 4)) / 4 + (params.second * pow(x, 3) - 2 * expected * params.first * pow(x, 3)) / 3 - expected * params.second * pow(x, 2) + (pow(expected, 2) * params.first * pow(x, 2)) / 2 + pow(expected, 2) * params.second * x;
};

return f(x2, expected) - f(x1, expected);
Expand Down Expand Up @@ -339,19 +338,17 @@ namespace ksi

return f(x2, expected) - f(x1, expected);
}

};



/** Class for representation of a pair: double, std::size_t with operator< .*/
class distance_index
{
public:
double distance;
std::size_t index;

bool operator < (const distance_index & right);

bool operator < (const distance_index & right);
};
}
#endif

2 changes: 0 additions & 2 deletions source/auxiliary/utility-string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ std::vector<std::string> ksi::utility_string::splitString(std::string s, const c
return slowa;
}



std::string ksi::utility_string::trimString(std::string s)
{
std::string white (" \t\f\v\n\r");
Expand Down
12 changes: 12 additions & 0 deletions source/common/dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ std::size_t ksi::dataset::size() const
return data.size();
}

double ksi::dataset::get_cardinality() const
{
double cardinality {0.0};

for (const auto & p : data)
{
cardinality += p->getWeight();
}
return cardinality;
}



std::size_t ksi::dataset::getNumberOfAttributes() const
{
Expand Down
7 changes: 5 additions & 2 deletions source/common/dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ namespace ksi
/** @return returns number of data items in the dataset */
std::size_t size() const;

/** @return sum of weights of all items in the train dataset
@date 2024-03-08 */
double get_cardinality() const ;

/** @return returns number of attributes in a datum */
std::size_t getNumberOfAttributes() const;

Expand Down Expand Up @@ -117,8 +121,7 @@ namespace ksi
* @date 2019-01-22
*/
std::vector<std::vector<ext_fuzzy_number_gaussian>> getMatrix(ext_fuzzy_number_gaussian) const ;



/** A method get r-th datum from the dataset. The method does not copy the datum!
* @return a pointer to the datum or nullptr if r is illegal
* @param r index of datum
Expand Down
7 changes: 4 additions & 3 deletions source/descriptors/descriptor-gaussian.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ double ksi::descriptor_gaussian::getMembership(double x)
{
if (_stddev <= 0.0)
{
std::stringstream ss;
ss << "illegal value of fuzzyfication of a gaussian set: " << NAZWA(_stddev) << " == " << _stddev;
throw ss.str();
// std::stringstream ss;
// ss << "illegal value of fuzzyfication of a gaussian set: " << NAZWA(_stddev) << " == " << _stddev;
// throw ss.str();
_stddev = 0.000'001; // tiny positive value.
}
double diff = x - _mean;
return last_membership = std::exp(-(diff * diff) / (2 * _stddev * _stddev));
Expand Down
2 changes: 0 additions & 2 deletions source/descriptors/descriptor-sigmoidal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ double ksi::descriptor_sigmoidal::getCoreMean() const
return std::nan("");
}


double ksi::descriptor_sigmoidal::getMembership (double x)
{
try
Expand All @@ -82,7 +81,6 @@ ksi::descriptor * ksi::descriptor_sigmoidal::clone() const

ksi::descriptor_sigmoidal::~descriptor_sigmoidal()
{

}

std::ostream& ksi::descriptor_sigmoidal::print(std::ostream& ss) const
Expand Down
2 changes: 1 addition & 1 deletion source/descriptors/descriptor-triangular.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ std::ostream& ksi::descriptor_triangular::printLinguisticDescription(std::ostrea
return ss;
}

std::vector< double > ksi::descriptor_triangular::getMAconsequenceParameters() const
std::vector<double> ksi::descriptor_triangular::getMAconsequenceParameters() const
{
return { _support_min, _core, _support_max };
}
Expand Down
Loading

0 comments on commit bfb9377

Please sign in to comment.