1 // This is mul/clsfy/clsfy_smo_base.cxx
2 #include "clsfy_smo_base.h"
3 //:
4 // \file
5 // \author Ian Scott
6 // \date 14-Nov-2001
7 // \brief Sequential Minimum Optimisation algorithm
8 // This code is based on the C++ code of
9 // Xianping Ge, ( http://www.ics.uci.edu/~xge ) which he kindly
10 // put in the public domain.
11 // That code was in turn based on the algorithms of
12 // John Platt, ( http://research.microsoft.com/~jplatt ) described in
13 // Platt, J. C. (1998). Fast Training of Support Vector Machines Using Sequential
14 // Minimal Optimisation. In Advances in Kernel Methods - Support Vector Learning.
15 // B. Scholkopf, C. Burges and A. Smola, MIT Press: 185-208. and other papers.
16 
17 #include <cassert>
18 
19 // ----------------------------------------------------------------
20 
error() const21 double clsfy_smo_base::error() const
22 {
23   return error_;
24 }
25 
26 // ----------------------------------------------------------------
27 
28 //: Access the data points
data_point(unsigned long l)29 const vnl_vector<double> & clsfy_smo_base::data_point(unsigned long l)
30 {
31   data_->set_index(l);
32   return data_->current();
33 }
34 
35 // ----------------------------------------------------------------
36 
learned_func(int k)37 double clsfy_smo_base::learned_func(int k)
38 {
39   double s = -b_;
40   const unsigned long N = data_->size();
41   for (unsigned int i=0; i<N; i++)
42     if (alph_[i] > 0)
43       s += alph_[i]*target_[i]*kernel(i,k);
44 
45   return s;
46 }
47 
48 // ----------------------------------------------------------------
49 
50 //: Get the optimised parameters
lagrange_mults() const51 const vnl_vector<double>& clsfy_smo_base::lagrange_mults() const
52 {
53   return alph_;
54 }
55 
56 // ----------------------------------------------------------------
57 
58 //: Set the initial values of the parameters to be optimised.
59 // The caller is responsible for ensuring that the initial values
60 // fulfill the constraints;
set_lagrange_mults(const vnl_vector<double> & lagrange_mults)61 void clsfy_smo_base::set_lagrange_mults(const vnl_vector<double>& lagrange_mults)
62 {
63   alph_ = lagrange_mults;
64 }
65 
66 // ----------------------------------------------------------------
67 
bias() const68 double clsfy_smo_base::bias() const
69 {
70   return b_;
71 }
72 
73 // ----------------------------------------------------------------
74 
75 //: Reseeds the internal random number generator.
76 // To achieve quasi-random initialisation use;
77 // \code
78 // #include <vcl_compiler.h>
79 // #include <iostream>
80 // #include <ctime>
81 // ..
82 // sampler.reseed(std::time(0));
83 // \endcode
reseed(unsigned long seed)84 void clsfy_smo_base::reseed(unsigned long seed)
85 {
86   rng_.reseed(seed);
87 }
88 
89 // ----------------------------------------------------------------
90 
91 //: Amount by which a sample can violate the KKT conditions
tolerance() const92 const double& clsfy_smo_base::tolerance() const
93 {
94   return tolerance_;
95 }
96 
97 // ----------------------------------------------------------------
98 
99 //: Set the amount by which a sample can violate the KKT conditions.
100 // Default value is 0.001
set_tolerance(double tolerance)101 void clsfy_smo_base::set_tolerance(double tolerance)
102 {
103   assert(tolerance >= 0.0);
104   tolerance_ = tolerance;
105 }
106 
107 // ----------------------------------------------------------------
108 
109 //: Tolerance on several equalities.
110 // Including testing if a Lagrange multiplier is at one of the bounds.
eps() const111 double clsfy_smo_base::eps() const
112 {
113   return eps_;
114 }
115 
116 // ----------------------------------------------------------------
117 
118 //: Set the tolerance on several equalities.
119 // Including testing if a Lagrange multiplier is at one of the bounds.
120 // Default value is 0.001;
set_eps(double eps)121 void clsfy_smo_base::set_eps(double eps)
122 {
123   assert(eps >= 0.0);
124   eps_ = eps;
125 }
126 
127 // ----------------------------------------------------------------
128 
clsfy_smo_base()129 clsfy_smo_base::clsfy_smo_base() : rng_(9667566) {}
130 
131 // ----------------------------------------------------------------
132 
~clsfy_smo_base()133 clsfy_smo_base::~clsfy_smo_base()
134 {
135   delete data_;
136 }
137 
138 // ----------------------------------------------------------------
139 
error_rate()140 double clsfy_smo_base::error_rate()
141 {
142     int n_total = 0;
143     int n_error = 0;
144     for (unsigned int i=0; i<data_->size(); ++i) {
145       if ((learned_func(i) > 0) != (target_[i] > 0)) // meaning: signs are different
146         ++n_error;
147       ++n_total;
148     }
149     return double(n_error)/double(n_total);
150 }
151