AlgoPlus v0.1.0
Loading...
Searching...
No Matches
log_reg.h
1#ifndef LOG_REG_H
2#define LOG_REG_H
3
4#ifdef __cplusplus
5#include <cassert>
6#include <cmath>
7#include <iostream>
8#include <random>
9#include <vector>
10#include "../../activation/activation_functions.h"
11#include "../../metrics/metrics.h"
12#endif
13
20 private:
21 double learning_rate_;
22 double bias_;
23 int epochs_;
24 std::vector<double> predictors_;
25 std::vector<std::vector<double>> data_;
26 std::vector<double> labels_;
27
32 double h_theta(const int index) {
33 double z = this->bias_;
34 for (int i = 0; i < this->predictors_.size(); i++) {
35 z += this->data_[index][i] * this->predictors_[i];
36 }
37
38 return activation::sigmoid(z);
39 }
40
44 void verbose_acc_step_() {
45 std::vector<double> y_pred;
46 for (int i = 0; i < this->data_.size(); i++) {
47 double h = h_theta(i);
48
49 if (h < 0.5) {
50 y_pred.push_back(0.0);
51 } else {
52 y_pred.push_back(1.0);
53 }
54 }
55
56 std::cout << "Accuracy: " << metrics::accuracy_score(this->labels_, y_pred)
57 << " | f1_score: " << metrics::f1_score(this->labels_, y_pred)
58 << " | Recall: " << metrics::recall(this->labels_, y_pred)
59 << " | Precision: " << metrics::precision(this->labels_, y_pred) << '\n';
60 }
61
62 public:
72 explicit logistic_regression(const std::vector<std::vector<double>> data,
73 const double lr = 0.001, const double bias = 0.001,
74 const int epochs = 10) {
75 assert(!data.empty());
76 assert(epochs >= 0);
77 assert(lr > 0);
78
79 for (auto& x : data) {
80 assert(x.back() == 0 || x.back() == 1);
81 }
82
83 this->learning_rate_ = lr;
84 this->epochs_ = epochs;
85 this->data_ = data;
86 this->bias_ = bias;
87 for (auto& x : data) {
88 this->labels_.push_back(x.back());
89 }
90
91 std::random_device rd;
92 std::mt19937 gen(rd());
93 std::uniform_real_distribution<double> dist(-1.0, 1.0);
94
95 this->predictors_ = std::vector<double>(data[0].size() - 1);
96 for (int i = 0; i < this->predictors_.size(); i++) {
97 this->predictors_[i] = dist(gen);
98 }
99 }
100
105 inline void fit() {
106 for (int epoch = 0; epoch < this->epochs_; epoch++) {
107 for (size_t j = 0; j < this->data_.size(); j++) {
108 double h = h_theta(j);
109 for (size_t k = 0; k < (this->data_[0].size() - 1); k++) {
110 double gradient = (h - this->labels_[j]) * this->data_[j][k];
111 this->predictors_[k] = this->predictors_[k] - (this->learning_rate_ * gradient);
112 }
113 }
114
115 std::cout << "Epoch: " << (epoch + 1) << ": ";
116 verbose_acc_step_();
117 }
118 }
119};
120
121#endif
void fit()
fits the input to the classifier, performs gradient descent using the predictors and learning rate.
Definition log_reg.h:105
logistic_regression(const std::vector< std::vector< double > > data, const double lr=0.001, const double bias=0.001, const int epochs=10)
default constructor for logistic regression class
Definition log_reg.h:72
double f1_score(const std::vector< double > &y, const std::vector< double > &y_pred)
f1 score function: [2 * precision * recall / precision + recall]
Definition metrics.h:99
double accuracy_score(const std::vector< double > &y, const std::vector< double > &y_pred)
accuracy score function[(tp + tn) / (tp + tn + fp + fn)]
Definition metrics.h:81
double recall(const std::vector< double > &y, const std::vector< double > &y_pred)
recall function[tp / tp + fn]
Definition metrics.h:72
double precision(const std::vector< double > &y, const std::vector< double > &y_pred)
precision function[tp / tp + fp]
Definition metrics.h:90