-
Notifications
You must be signed in to change notification settings - Fork 0
/
lr.cpp
130 lines (106 loc) · 3.97 KB
/
lr.cpp
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <math.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <vector>
#include <valarray>
#include "util.cpp"
using namespace std;
void test_accuracy(vector<double> weights, vector<vector<double>> testing_x, vector<double> testing_y) {
double accuracy = 0.0, tmp;
int testing_rows = testing_x.size();
for(int i = 0; i < testing_rows; i++) {
tmp = vector_dot_product(weights, testing_x[i]);
if(tmp >= 0) {
tmp = 1;
} else {
tmp = -1;
}
if(tmp == testing_y[i]) accuracy += 1;
}
cout << "accuracy " << accuracy / testing_rows << endl;
}
int main()
{
// read file
// string filename = "./python/datasets/breast_cancer/data.csv";
string filename = "./python/datasets/make_circles.csv";
vector<vector<string>> s_matrix = CSVtoMatrix(filename);
vector<vector<double>> f_matrix = stringTodoubleMatrix(s_matrix);
// random_shuffle(f_matrix.begin(), f_matrix.end());
// Init features, labels and weights
int total_rows = f_matrix.size();
cout << "\nNumber of rows = " << total_rows << endl;
int total_cols = f_matrix[0].size() - 1;
cout << "\nNumber of cols = " << total_cols << endl;
vector<vector<double>> features(total_rows, vector<double>(total_cols));
// Init labels (rows of f_matrix)
vector<double> labels(total_rows);
int training_rows = 400;
int testing_rows = total_rows - training_rows;
vector<vector<double>> training_x(training_rows, vector<double>(total_cols));
vector<vector<double>> testing_x(testing_rows, vector<double>(total_cols));
vector<double> training_y(training_rows);
vector<double> testing_y(testing_rows);
// Fill the features matrix and labels vector
for (int i = 0; i < total_rows; i++) {
for (int j = 0; j < total_cols; j++) {
if(i < training_rows) {
training_x[i][j] = f_matrix[i][j];
} else {
testing_x[i - training_rows][j] = f_matrix[i][j];
}
}
if(i < training_rows) {
training_y[i] = f_matrix[i][total_cols];
} else {
testing_y[i - training_rows] = f_matrix[i][total_cols];
}
}
// Init weights
// Init weight vector with zeros (cols of features)
vector<double> weights(total_cols);
for (int i = 0; i < total_cols; i++) {
weights[i] = 0;
// weights[i] = RandomFloat(-0.1, 0.1);
}
// Polynomial Simulated Sigmoid Function
double poly_deg = 3;
// double poly_deg = 7;
vector<double> coeffs = {0.5009117914058876, 0.19832549320270615, -0.0001824312536790085, -0.0044735810103240774};
// vector<double> coeffs = {0.50054, 0.19688, -0.00014, -0.00544, 0.000005, 0.000075, -0.00000004, -0.0000003};
// Parameters Settings
int col_A = 1;
int col_B = total_cols - col_A;
double learning_rate = 0.001;
int iter_times = 20;
// Calculate gradient descents in the plaintext domain
vector<double> delta_w(total_cols, 0.0);
double w_x, tmp;
for(int iter = 0; iter < iter_times; iter++) {
cout << "iter " << iter << endl;
fill(delta_w.begin(), delta_w.end(), 0);
for(int i = 0; i < training_rows; i++) {
w_x = vector_dot_product(weights, training_x[i]);
tmp = 0.0;
for(int j = 0; j <= poly_deg; j++) {
tmp += coeffs[j] * pow(-1 * training_y[i], j + 1) * pow(w_x, j);
}
for(int j = 0; j < total_cols; j++) {
delta_w[j] += tmp * training_x[i][j];
}
}
for(int i = 0; i < total_cols; i++) {
weights[i] = weights[i] - learning_rate * delta_w[i] / training_rows;
}
// Show results
for(int i = 0; i < 10; i++) {
cout << weights[i] << " ";
}
cout << endl;
test_accuracy(weights, training_x, training_y);
test_accuracy(weights, testing_x, testing_y);
}
return 0;
}