6 #ifndef PERCEPTRONPRIMAL__HPP
7 #define PERCEPTRONPRIMAL__HPP
14 namespace classifier {
15 using namespace std::chrono;
24 Solution *initial_solution =
nullptr);
26 bool train()
override;
28 double evaluate(
const Point<T> &p,
bool raw_value =
false)
override;
39 double q = 2,
double rate = 0.5,
Solution *initial_solution =
nullptr);
41 bool train()
override;
43 double evaluate(
const Point<T> &p,
bool raw_value =
false)
override;
56 KernelType kernel_type,
double kernel_param = 0,
57 double rate = 0.5,
Solution *initial_solution =
nullptr);
60 Solution *initial_solution =
nullptr);
62 bool train()
override;
73 double kernel_param = 0,
double gamma = 0,
double rate = 0.5,
74 Solution *initial_solution =
nullptr);
76 bool train()
override;
89 this->samples = mltk::make_data<T>(samples);
94 size_t epoch = 0, ite = 0;
100 mltk::random_init<double>(this->weights, this->samples->
dim(), this->seed);
101 this->samples->
shuffle(this->seed);
104 while (epoch < this->MAX_EPOCH) {
106 for (
auto it = this->samples->begin(); it != this->samples->end(); ++it) {
108 int pred = ((
mltk::dot(weights, *point) + bias) >= 0) ? 1 : -1;
110 if (point->Y() != pred) {
111 weights += this->rate * (*point) * point->
Y();
112 bias += this->rate * bias;
117 if (ite > this->MAX_UP) {
124 if (stop || this->
timer.elapsed() > this->max_time || errors == 0)
break;
127 for (
auto it = this->samples->begin(); it != this->samples->end(); ++it) {
129 double func = point.Y() * (
mltk::dot(weights, point) + bias);
131 if (point.Y() == 1 && func < gamma1) gamma1 = func;
132 if (point.Y() == -1 && func < gamma2) gamma2 = func;
134 double rmargin = (fabs(gamma1) > fabs(gamma2)) ? fabs(gamma2) : fabs(gamma1);
135 double mmargin = (fabs(gamma1) + fabs(gamma2)) / 2;
136 if(fabs(gamma2) > fabs(gamma1)){
137 bias += fabs(mmargin - rmargin);
139 bias -= fabs(mmargin - rmargin);
141 this->solution.w = weights;
142 this->solution.bias = bias;
144 return (errors == 0);
151 return ((
mltk::dot(weights, p) + bias) >= 0) ? 1 : -1;
159 PerceptronPrimal<T>::PerceptronPrimal(std::shared_ptr<
Data<T> > samples,
double q,
double rate,
161 this->samples = samples;
164 if (initial_solution)
165 this->solution = *initial_solution;
169 PerceptronPrimal<T>::PerceptronPrimal(
const Data<T> &samples,
double q,
double rate,
170 Solution *initial_solution) {
171 this->samples = mltk::make_data<T>(samples);
174 if (initial_solution)
175 this->solution = *initial_solution;
181 size_t size = this->samples->size(), dim = this->samples->dim();
182 int i, j, e = 0, idx;
183 double y, time = this->start_time + this->max_time;
185 std::vector<double> func(size, 0);
187 std::vector<int> index = this->samples->getIndex();
189 if (this->solution.w.empty()) this->solution.w.resize(dim);
190 this->solution.bias = 0;
191 this->solution.norm = 0.0;
194 while (this->
timer.elapsed() - time <= 0) {
195 for (e = 0, i = 0; i < size; ++i) {
197 auto p = this->samples->point(idx);
202 for (func[idx] = this->solution.bias, j = 0; j < dim; ++j)
203 func[idx] += this->solution.w[j] * x[j];
206 if (y * func[idx] <= 0.0) {
207 for (this->solution.norm = 0.0, j = 0; j < dim; ++j) {
208 this->solution.w[j] += this->rate * y * x[j];
209 this->solution.norm += this->solution.w[j] * this->solution.w[j];
211 this->solution.norm = sqrt(this->solution.norm);
212 this->solution.bias += this->rate * y;
215 }
else if (this->steps > 0 && e > 1)
break;
221 if (this->steps > this->MAX_IT)
break;
222 if (this->ctot > this->MAX_UP)
break;
235 double q,
double rate,
Solution *initial_solution) {
236 this->samples = mltk::make_data<T>(samples);
240 if (initial_solution)
241 this->solution = *initial_solution;
246 size_t i, j, k, e, s, r, dim = this->samples->
dim();
247 size_t size = this->samples->
size(), n = dim;
248 int idx, sign = 1, n_temp = 0, largn = 0;
249 double norm = this->solution.norm, lambda = 1.0, y, time = this->start_time + this->max_time;
250 double sumnorm = 0.0, bias = this->solution.bias, largw = 0.0, largw_temp = 0.0;
252 std::vector<double> func = this->solution.func.X(), w = this->solution.w.X();
254 std::vector<int> index = this->samples->
getIndex();
255 std::shared_ptr<Point<T> > p;
257 if (func.empty()) func.resize(size);
258 if (w.empty()) w.resize(dim);
261 while (this->
timer.elapsed() - time <= 0) {
262 for (e = 0, i = 0; i < size; ++i) {
264 p = this->samples->
point(idx);
269 for (func[idx] = bias, j = 0; j < dim; ++j) {
270 func[idx] += w[j] * x[j];
274 if (y * func[idx] <= this->gamma * norm - this->samples->
point(idx)->Alpha() * this->flexible) {
275 lambda = (norm != 0.0) ? (1 - this->rate * this->gamma / norm) : 1;
276 for (r = 0; r < size; ++r) {
277 std::shared_ptr<Point<T> > b = this->samples->
point(r);
278 b->Alpha() *= lambda;
282 if (this->q == 1.0) {
283 for (sumnorm = 0.0, j = 0; j < dim; ++j) {
284 sign = (w[j] < 0) ? -1 : 1;
285 lambda = (norm > 0 && w[j] != 0) ? this->gamma * sign : 0;
286 w[j] += this->rate * (y * x[j] - lambda);
287 sumnorm += fabs(w[j]);
290 }
else if (this->q == 2.0) {
291 for (sumnorm = 0.0, j = 0; j < dim; ++j) {
292 lambda = (norm > 0 && w[j] != 0) ? w[j] * this->gamma / norm : 0;
293 w[j] += this->rate * (y * x[j] - lambda);
294 sumnorm += w[j] * w[j];
296 norm = sqrt(sumnorm);
297 }
else if (this->q == -1.0) {
298 largw_temp = fabs(w[0]);
300 for (j = 0; j < dim; ++j) {
301 if (largw == 0 || fabs(largw - fabs(w[j])) / largw < this->EPS) {
302 sign = (w[j] < 0) ? -1 : 1;
303 lambda = (norm > 0 && w[j] != 0) ? this->gamma * sign / n : 0;
304 w[j] += this->rate * (y * x[j] - lambda);
306 w[j] += this->rate * (y * x[j]);
309 if (fabs(largw_temp - fabs(w[j])) / largw_temp < this->EPS)
311 else if (fabs(w[j]) > largw_temp) {
312 largw_temp = fabs(w[j]);
320 if (n > largn) largn = n;
322 for (sumnorm = 0, j = 0; j < dim; ++j) {
323 lambda = (norm > 0 && w[j] != 0) ? w[j] * this->gamma *
324 std::pow(fabs(w[j]), this->q - 2.0) *
325 std::pow(norm, 1.0 - this->q) : 0;
326 w[j] += this->rate * (y * x[j] - lambda);
327 sumnorm += std::pow(fabs(w[j]), this->q);
329 norm = std::pow(sumnorm, 1.0 / this->q);
331 bias += this->rate * y;
332 p->Alpha() += this->rate;
335 k = (i > s) ? s++ : e;
341 }
else if (this->steps > 0 && e > 1 && i > s)
break;
347 if (this->steps > this->MAX_IT)
break;
348 if (this->ctot > this->MAX_UP)
break;
351 this->solution.norm = norm;
352 this->solution.bias = bias;
353 this->solution.w = w;
361 size_t dim = this->samples->
dim();
363 if (p.
X().size() != dim) {
364 std::cerr <<
"The point must have the same dimension of the feature set!" << std::endl;
368 for (func = this->solution.bias, i = 0; i < dim; i++) {
369 func += this->solution.w[i] * p[i];
372 if (!raw_value)
return (func >= this->solution.margin * this->solution.norm) ? 1 : -1;
378 double kernel_param,
double rate,
Solution *initial_solution) {
379 this->samples = mltk::make_data<T>(samples);
380 if (initial_solution) {
381 this->solution = *initial_solution;
382 this->alpha = (*initial_solution).
alpha;
385 this->kernel =
new Kernel<T>(kernel_type, kernel_param);
389 PerceptronDual<T>::PerceptronDual(
const Data<T>& samples,
double rate, Solution *initial_solution) {
390 this->samples = mltk::make_data<T>(samples);
391 if (initial_solution) {
392 this->solution = *initial_solution;
393 this->alpha = (*initial_solution).alpha;
395 this->initial = initial_solution;
397 this->kernel =
nullptr;
403 size_t e, i, j, idx, r, size = this->samples->size(), dim = this->samples->dim();
404 double norm = this->solution.norm, time = this->start_time + this->max_time;
405 double bias = this->solution.bias, f;
406 const double sqrate = this->rate * this->rate;
407 const double tworate = 2 * this->rate;
408 std::vector<int> index(size);
409 std::vector<double> func(size, 0.0), Kv;
410 std::vector<std::shared_ptr<Point<T> > > points = this->samples->points();
411 if(!this->kernel) this->kernel =
new Kernel<T>(mltk::KernelType::INNER_PRODUCT);
412 this->kernel->compute(this->samples);
413 dMatrix *K = this->kernel->getKernelMatrixPointer();
415 iota(index.begin(), index.end(), 0);
416 if (this->alpha.empty()) {
417 this->alpha.assign(size, 0.0);
424 auto time_elapsed = this->
timer.elapsed() - time;
425 while (time_elapsed <= 0) {
426 for (e = 0, i = 0; i < size; ++i) {
428 y = points[idx]->Y();
431 for (f = bias, r = 0; r < size; ++r)
432 f += this->alpha[r] * points[index[r]]->Y() * (*K)[idx][index[r]];
437 norm = std::sqrt(norm * norm + tworate * points[idx]->Y() * (func[idx] - bias) + sqrate * (*K)[idx][idx]);
438 this->alpha[i] += this->rate;
439 bias += this->rate * y;
441 }
else if (this->steps > 0 && e > 1)
break;
443 time_elapsed = this->
timer.elapsed() - time;
448 if (this->steps > this->MAX_IT)
break;
449 if (this->ctot > this->MAX_UP)
break;
451 this->solution.bias = bias;
452 this->solution.norm = norm;
453 this->solution.alpha = this->alpha;
454 this->solution.margin = 0.0;
455 this->solution.w.resize(dim);
457 for (i = 0; i < size; i++) {
458 for (j = 0; j < dim; j++) {
459 this->solution.w[j] += this->alpha[i] * points[i]->Y() * points[i]->X()[j];
468 double kernel_param,
double gamma,
double rate,
470 this->samples = mltk::make_data<T>(samples);
473 this->kernel =
new Kernel<T>(kernel_type, kernel_param);
475 if (initial_solution)
476 this->alpha = (*initial_solution).alpha;
481 size_t e, i, j, k, s, idx, r, size = this->samples->
size(), dim = this->samples->
dim();
482 double y, lambda, norm = this->solution.norm, time = this->start_time + this->max_time;
483 double bias = this->solution.bias;
484 const double sqrate = this->rate * this->rate;
485 const double tworate = 2 * this->rate;
486 std::vector<int> index = this->samples->
getIndex();
487 std::vector<double> func = this->solution.func.X(), Kv;
488 this->kernel->compute(this->samples);
489 dMatrix *K = this->kernel->getKernelMatrixPointer();
491 if(this->alpha.empty()){
492 this->alpha.resize(this->samples->
size());
495 if (func.empty()) { func.resize(size); }
499 while (this->
timer.elapsed() - time <= 0) {
500 for (e = 0, i = 0; i < size; ++i) {
502 y = (*this->samples)[idx]->Y();
506 if (y * func[idx] - this->gamma * norm <= 0) {
507 lambda = (this->gamma) ? (1 - this->rate * this->gamma / norm) : 1;
510 for (r = 0; r < size; ++r) {
511 (*this->samples)[r]->Alpha() *= lambda;
512 func[r] = lambda * func[r] + this->rate * y * ((*K)[idx][r] + 1) + bias * (1 - lambda);
515 norm = sqrt(norm * norm + tworate * (*this->samples)[idx]->Y() * lambda * (func[idx] - bias) +
516 sqrate * (*K)[idx][idx]);
517 (*this->samples)[idx]->Alpha() += this->rate;
519 bias += this->rate * y;
521 k = (i > s) ? ++s : e;
527 }
else if (this->steps > 0 && e > 1 && i > s)
break;
533 if (this->steps > this->MAX_IT)
break;
534 if (this->ctot > this->MAX_UP)
break;
538 this->solution.bias = bias;
539 this->solution.norm = norm;
540 this->solution.func = func;
541 this->solution.w.resize(dim);
542 this->solution.alpha.resize(size);
543 for (i = 0; i < dim; i++) {
544 for (j = 0; j < size; j++) {
545 this->solution.alpha[j] = (*this->samples)[j]->Alpha();
546 this->solution.w[i] +=
547 (*this->samples)[j]->Alpha() * (*this->samples)[j]->Y() * (*this->samples)[j]->X()[i];
PointPointer< T > point(int index) const
Returns a shared pointer to the point with the given index.
Definition: Data.hpp:1510
size_t size() const
Returns the size of the dataset.
Definition: Data.hpp:208
void setIndex(std::vector< int > index)
Set the index vector for the data.
Definition: Data.hpp:1754
void setPoint(int index, std::shared_ptr< Point< T > > p)
setPoint Set the point in a position of the data.
Definition: Data.hpp:1515
std::vector< int > getIndex() const
Returns the vector of indexes.
Definition: Data.hpp:1695
size_t dim() const
Returns the dimension of the dataset.
Definition: Data.hpp:213
void shuffle(const size_t &seed=42)
Shuffle the data with a given seed.
Definition: Data.hpp:1349
Rep const & X() const
Returns the attributes representation of the point (std::vector by default).
Definition: Point.hpp:139
double const & Y() const
Returns the class or value of the point.
Definition: Point.hpp:152
Definition: Solution.hpp:13
std::vector< double > alpha
Alpha Vector for Dual methods.
Definition: Solution.hpp:21
Definition: Perceptron.hpp:80
bool train() override
Function that execute the training phase of a Learner.
Definition: Perceptron.hpp:93
std::string getFormulationString() override
getFormulationString Returns a string that represents the formulation of the learner (Primal or Dual)...
Definition: Perceptron.hpp:155
double evaluate(const Point< T > &p, bool raw_value) override
Returns the class of a feature point based on the trained Learner.
Definition: Perceptron.hpp:147
Definition: DualClassifier.hpp:16
Wrapper for the implementation of the Perceptron dual algorithm.
Definition: Perceptron.hpp:50
bool train() override
Function that execute the training phase of a Learner.
Definition: Perceptron.hpp:402
Wrapper for the implementation of the Perceptron dual with fixed margin algorithm.
Definition: Perceptron.hpp:69
bool train() override
Function that execute the training phase of a Learner.
Definition: Perceptron.hpp:480
Wrapper for the implementation of the Perceptron primal with fixed margin algorithm.
Definition: Perceptron.hpp:35
double evaluate(const Point< T > &p, bool raw_value=false) override
Returns the class of a feature point based on the trained Learner.
Definition: Perceptron.hpp:358
bool train() override
Function that execute the training phase of a Learner.
Definition: Perceptron.hpp:245
Wrapper for the implementation of the Perceptron primal algorithm.
Definition: Perceptron.hpp:21
double evaluate(const Point< T > &p, bool raw_value=false) override
Returns the class of a feature point based on the trained Learner.
Definition: Perceptron.hpp:229
bool train() override
Function that execute the training phase of a Learner.
Definition: Perceptron.hpp:180
Definition: PrimalClassifier.hpp:14
double evaluate(const Point< T > &p, bool raw_value=false) override
Returns the class of a feature point based on the trained Learner.
Definition: PrimalClassifier.hpp:42
A helper class to measure execution time for benchmarking purposes.
Definition: ThreadPool.hpp:503
UFJF-MLTK main namespace for core functionalities.
Definition: classifier/Classifier.hpp:11
T dot(const Point< T, R > &p, const Point< T, R > &p1)
Computes the dot product with a vector.
Definition: Point.hpp:528
T max(const Point< T, R > &p)
Returns the max value of the point.
Definition: Point.hpp:544