-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinearRegression.cpp
More file actions
102 lines (83 loc) · 2.51 KB
/
Copy pathLinearRegression.cpp
File metadata and controls
102 lines (83 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <cmath>
#include <vector>
#include <numeric>
#include <iostream>
#include "LinearRegression.hpp"
#include <unistd.h>
#include "matplotlibcpp.h"
namespace plt = matplotlibcpp;
LinearRegression::LinearRegression(unsigned int iterations, double lr) :
_iterations(iterations),
_lr(lr),
_intercept(0.),
_coef(0.),
_mag(1.)
{}
LinearRegression::LinearRegression() :
_iterations(0.),
_lr(0.),
_intercept(0.),
_coef(0.),
_mag(1.)
{}
void LinearRegression::fit(std::vector<double> const X, std::vector<double> const Y) {
double size = X.size();
auto X_Normalized = NormalizeData(X);
auto minmax = std::minmax_element(X.begin(), X.end());
for (int iter = 0; iter < _iterations; iter++) {
plt::clf();
plt::scatter(X, Y, 5.);
plt::plot({*minmax.first, *minmax.second},{predict(*minmax.first), predict(*minmax.second)}, "");
plt::pause(std::numeric_limits<double>::epsilon());
plt::draw();
std::cout << iter << " iterations. Score: " << score(X, Y) << std::endl;
double tmpT0 = 0.;
double tmpT1 = 0.;
for (auto i=0; i < size; i++) {
double estimatePrice = _intercept + (_coef * X_Normalized[i]);
double error = estimatePrice - Y[i];
tmpT0 += error;
tmpT1 += error * X_Normalized[i];
}
_intercept -= _lr * tmpT0 / size;
_coef -= _lr * tmpT1 / size;
}
}
std::vector<double> LinearRegression::NormalizeData(std::vector<double> const & data) {
std::vector<double> output = data;
double mod = 0.0;
std::for_each(data.begin(), data.end(), [&](double data) {
mod += std::pow(data, 2);
});
_mag = std::sqrt(mod);
if (_mag == 0) {
throw std::logic_error("The input vector is a zero vector");
}
std::for_each(output.begin(), output.end(), [this](double & data) {
data /= _mag;
});
return output;
}
double LinearRegression::predict(double X, bool normalizeX) const {
if (normalizeX == true)
X /= _mag;// normalization reasons
return (_coef * X + _intercept);
}
double LinearRegression::score(std::vector<double> const & X, std::vector<double> const & Y) {
auto X_iter = X.cbegin();
double RMSE = 0.;
std::for_each(Y.cbegin(), Y.cend(), [&](double value) {
RMSE += std::pow(value - predict(*X_iter),2);
X_iter++;
});
return std::sqrt(RMSE / Y.size());
}
double LinearRegression::coef() {return _coef / _mag;}
double LinearRegression::intercept() {return _intercept;}
void LinearRegression::set_intercept(double intercept) {
_intercept = intercept;
}
void LinearRegression::set_coef(double coef) {
_coef = coef;
}
LinearRegression::~LinearRegression() {}