SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
SVM.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
11 #include <shogun/lib/common.h>
12 #include <shogun/io/SGIO.h>
13 #include <shogun/base/Parallel.h>
14 #include <shogun/base/Parameter.h>
15 
19 
20 #include <string.h>
21 
22 using namespace shogun;
23 
24 CSVM::CSVM(int32_t num_sv)
26 {
27  set_defaults(num_sv);
28 }
29 
32 {
33  set_defaults();
34  set_C(C,C);
35  set_labels(lab);
36  set_kernel(k);
37 }
38 
40 {
41  SG_UNREF(mkl);
42 }
43 
44 void CSVM::set_defaults(int32_t num_sv)
45 {
46  SG_ADD(&C1, "C1", "", MS_AVAILABLE);
47  SG_ADD(&C2, "C2", "", MS_AVAILABLE);
48  SG_ADD(&svm_loaded, "svm_loaded", "SVM is loaded.", MS_NOT_AVAILABLE);
49  SG_ADD(&epsilon, "epsilon", "", MS_AVAILABLE);
50  SG_ADD(&tube_epsilon, "tube_epsilon",
51  "Tube epsilon for support vector regression.", MS_AVAILABLE);
52  SG_ADD(&nu, "nu", "", MS_AVAILABLE);
53  SG_ADD(&objective, "objective", "", MS_NOT_AVAILABLE);
54  SG_ADD(&qpsize, "qpsize", "", MS_NOT_AVAILABLE);
55  SG_ADD(&use_shrinking, "use_shrinking", "Shrinking shall be used.",
57  SG_ADD((CSGObject**) &mkl, "mkl", "MKL object that svm optimizers need.",
59  SG_ADD(&m_linear_term, "linear_term", "Linear term in qp.",
61 
62  callback=NULL;
63  mkl=NULL;
64 
65  set_loaded_status(false);
66 
67  set_epsilon(1e-5);
68  set_tube_epsilon(1e-2);
69 
70  set_nu(0.5);
71  set_C(1,1);
72 
73  set_objective(0);
74 
75  set_qpsize(41);
76  set_bias_enabled(true);
77  set_linadd_enabled(true);
80 
81  if (num_sv>0)
82  create_new_model(num_sv);
83 }
84 
85 bool CSVM::load(FILE* modelfl)
86 {
87  bool result=true;
88  char char_buffer[1024];
89  int32_t int_buffer;
90  float64_t double_buffer;
91  int32_t line_number=1;
92 
94 
95  if (fscanf(modelfl,"%4s\n", char_buffer)==EOF)
96  {
97  result=false;
98  SG_ERROR("error in svm file, line nr:%d\n", line_number)
99  }
100  else
101  {
102  char_buffer[4]='\0';
103  if (strcmp("%SVM", char_buffer)!=0)
104  {
105  result=false;
106  SG_ERROR("error in svm file, line nr:%d\n", line_number)
107  }
108  line_number++;
109  }
110 
111  int_buffer=0;
112  if (fscanf(modelfl," numsv=%d; \n", &int_buffer) != 1)
113  {
114  result=false;
115  SG_ERROR("error in svm file, line nr:%d\n", line_number)
116  }
117 
118  if (!feof(modelfl))
119  line_number++;
120 
121  SG_INFO("loading %ld support vectors\n",int_buffer)
122  create_new_model(int_buffer);
123 
124  if (fscanf(modelfl," kernel='%s'; \n", char_buffer) != 1)
125  {
126  result=false;
127  SG_ERROR("error in svm file, line nr:%d\n", line_number)
128  }
129 
130  if (!feof(modelfl))
131  line_number++;
132 
133  double_buffer=0;
134 
135  if (fscanf(modelfl," b=%lf; \n", &double_buffer) != 1)
136  {
137  result=false;
138  SG_ERROR("error in svm file, line nr:%d\n", line_number)
139  }
140 
141  if (!feof(modelfl))
142  line_number++;
143 
144  set_bias(double_buffer);
145 
146  if (fscanf(modelfl,"%8s\n", char_buffer) == EOF)
147  {
148  result=false;
149  SG_ERROR("error in svm file, line nr:%d\n", line_number)
150  }
151  else
152  {
153  char_buffer[9]='\0';
154  if (strcmp("alphas=[", char_buffer)!=0)
155  {
156  result=false;
157  SG_ERROR("error in svm file, line nr:%d\n", line_number)
158  }
159  line_number++;
160  }
161 
162  for (int32_t i=0; i<get_num_support_vectors(); i++)
163  {
164  double_buffer=0;
165  int_buffer=0;
166 
167  if (fscanf(modelfl," \[%lf,%d]; \n", &double_buffer, &int_buffer) != 2)
168  {
169  result=false;
170  SG_ERROR("error in svm file, line nr:%d\n", line_number)
171  }
172 
173  if (!feof(modelfl))
174  line_number++;
175 
176  set_support_vector(i, int_buffer);
177  set_alpha(i, double_buffer);
178  }
179 
180  if (fscanf(modelfl,"%2s", char_buffer) == EOF)
181  {
182  result=false;
183  SG_ERROR("error in svm file, line nr:%d\n", line_number)
184  }
185  else
186  {
187  char_buffer[3]='\0';
188  if (strcmp("];", char_buffer)!=0)
189  {
190  result=false;
191  SG_ERROR("error in svm file, line nr:%d\n", line_number)
192  }
193  line_number++;
194  }
195 
196  set_loaded_status(result);
198  return result;
199 }
200 
201 bool CSVM::save(FILE* modelfl)
202 {
204 
205  if (!kernel)
206  SG_ERROR("Kernel not defined!\n")
207 
208  SG_INFO("Writing model file...")
209  fprintf(modelfl,"%%SVM\n");
210  fprintf(modelfl,"numsv=%d;\n", get_num_support_vectors());
211  fprintf(modelfl,"kernel='%s';\n", kernel->get_name());
212  fprintf(modelfl,"b=%+10.16e;\n",get_bias());
213 
214  fprintf(modelfl, "alphas=\[\n");
215 
216  for(int32_t i=0; i<get_num_support_vectors(); i++)
217  fprintf(modelfl,"\t[%+10.16e,%d];\n",
219 
220  fprintf(modelfl, "];\n");
221 
222  SG_DONE()
224  return true ;
225 }
226 
228  (CMKL* mkl, const float64_t* sumw, const float64_t suma))
229 {
230  SG_REF(m);
231  SG_UNREF(mkl);
232  mkl=m;
233 
234  callback=cb;
235 }
236 
238 {
239  int32_t n=get_num_support_vectors();
240 
241  if (m_labels && kernel)
242  {
243  objective=0;
244  for (int32_t i=0; i<n; i++)
245  {
246  int32_t ii=get_support_vector(i);
247  objective-=get_alpha(i)*((CBinaryLabels*) m_labels)->get_label(ii);
248 
249  for (int32_t j=0; j<n; j++)
250  {
251  int32_t jj=get_support_vector(j);
252  objective+=0.5*get_alpha(i)*get_alpha(j)*kernel->kernel(ii,jj);
253  }
254  }
255  }
256  else
257  SG_ERROR("cannot compute objective, labels or kernel not set\n")
258 
259  return objective;
260 }
261 
263 {
264  int32_t n=get_num_support_vectors();
265  float64_t regularizer=0;
266  float64_t loss=0;
267 
268 
269 
270  if (m_labels && kernel)
271  {
272  float64_t C2_tmp=get_C1();
273  if(C2>0)
274  {
275  C2_tmp=get_C2();
276  }
277 
278  for (int32_t i=0; i<n; i++)
279  {
280  int32_t ii=get_support_vector(i);
281  for (int32_t j=0; j<n; j++)
282  {
283  int32_t jj=get_support_vector(j);
284  regularizer-=0.5*get_alpha(i)*get_alpha(j)*kernel->kernel(ii,jj);
285  }
286 
287  loss-=(C1*(-((CBinaryLabels*) m_labels)->get_label(ii)+1)/2.0 + C2_tmp*(((CBinaryLabels*) m_labels)->get_label(ii)+1)/2.0 )*CMath::max(0.0, 1.0-((CBinaryLabels*) m_labels)->get_label(ii)*apply_one(ii));
288  }
289 
290  }
291  else
292  SG_ERROR("cannot compute objective, labels or kernel not set\n")
293 
294  return regularizer+loss;
295 }
296 
298 {
299  if (m_linear_term.vlen==0)
300  return NULL;
301  float64_t* a = SG_MALLOC(float64_t, m_linear_term.vlen);
302 
303  sg_memcpy(a, m_linear_term.vector,
304  m_linear_term.vlen*sizeof(float64_t));
305 
306  return a;
307 }
308 
310 {
311  ASSERT(linear_term.vector)
312 
313  if (!m_labels)
314  SG_ERROR("Please assign labels first!\n")
315 
316  int32_t num_labels=m_labels->get_num_labels();
317 
318  if (num_labels != linear_term.vlen)
319  {
320  SG_ERROR("Number of labels (%d) does not match number"
321  "of entries (%d) in linear term \n", num_labels, linear_term.vlen);
322  }
323 
324  m_linear_term=linear_term;
325 }
326 
328 {
329  return m_linear_term;
330 }
virtual float64_t apply_one(int32_t num)
virtual const char * get_name() const =0
void set_shrinking_enabled(bool enable)
Definition: SVM.h:179
bool use_shrinking
Definition: SVM.h:280
void set_bias_enabled(bool enable_bias)
#define SG_INFO(...)
Definition: SGIO.h:117
#define SG_RESET_LOCALE
Definition: SGIO.h:85
#define SG_DONE()
Definition: SGIO.h:156
float64_t get_C2()
Definition: SVM.h:167
float64_t compute_svm_primal_objective()
Definition: SVM.cpp:262
int32_t qpsize
Definition: SVM.h:278
The class Labels models labels, i.e. class assignments of objects.
Definition: Labels.h:43
virtual int32_t get_num_labels() const =0
bool(* callback)(CMKL *mkl, const float64_t *sumw, const float64_t suma)
Definition: SVM.h:284
virtual ~CSVM()
Definition: SVM.cpp:39
CLabels * m_labels
Definition: Machine.h:365
#define SG_ERROR(...)
Definition: SGIO.h:128
void set_callback_function(CMKL *m, bool(*cb)(CMKL *mkl, const float64_t *sumw, const float64_t suma))
Definition: SVM.cpp:227
float64_t kernel(int32_t idx_a, int32_t idx_b)
CMKL * mkl
Definition: SVM.h:287
virtual void set_linear_term(const SGVector< float64_t > linear_term)
Definition: SVM.cpp:309
A generic KernelMachine interface.
Definition: KernelMachine.h:51
float64_t epsilon
Definition: SVM.h:266
#define SG_REF(x)
Definition: SGObject.h:52
#define SG_SET_LOCALE_C
Definition: SGIO.h:84
void set_nu(float64_t nue)
Definition: SVM.h:107
float64_t get_C1()
Definition: SVM.h:161
virtual float64_t * get_linear_term_array()
Definition: SVM.cpp:297
void set_defaults(int32_t num_sv=0)
Definition: SVM.cpp:44
SGVector< float64_t > m_linear_term
Definition: SVM.h:261
float64_t compute_svm_dual_objective()
Definition: SVM.cpp:237
index_t vlen
Definition: SGVector.h:545
#define ASSERT(x)
Definition: SGIO.h:200
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:125
void set_bias(float64_t bias)
float64_t C2
Definition: SVM.h:274
void set_batch_computation_enabled(bool enable)
double float64_t
Definition: common.h:60
bool set_alpha(int32_t idx, float64_t val)
void set_objective(float64_t v)
Definition: SVM.h:209
void set_qpsize(int32_t qps)
Definition: SVM.h:143
virtual SGVector< float64_t > get_linear_term()
Definition: SVM.cpp:327
float64_t get_alpha(int32_t idx)
float64_t C1
Definition: SVM.h:272
static T max(T a, T b)
Definition: Math.h:164
bool set_support_vector(int32_t idx, int32_t val)
Multiple Kernel Learning.
Definition: MKL.h:85
int32_t get_support_vector(int32_t idx)
float64_t objective
Definition: SVM.h:276
float64_t tube_epsilon
Definition: SVM.h:268
bool load(FILE *svm_file)
Definition: SVM.cpp:85
#define SG_UNREF(x)
Definition: SGObject.h:53
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
CSVM(int32_t num_sv=0)
Definition: SVM.cpp:24
bool save(FILE *svm_file)
Definition: SVM.cpp:201
void set_linadd_enabled(bool enable)
The Kernel base class.
Binary Labels for binary classification.
Definition: BinaryLabels.h:37
bool svm_loaded
Definition: SVM.h:264
void set_epsilon(float64_t eps)
Definition: SVM.h:125
void set_kernel(CKernel *k)
#define SG_ADD(...)
Definition: SGObject.h:94
float64_t nu
Definition: SVM.h:270
virtual void set_labels(CLabels *lab)
Definition: Machine.cpp:65
void set_C(float64_t c_neg, float64_t c_pos)
Definition: SVM.h:118
bool create_new_model(int32_t num)
void set_loaded_status(bool loaded)
Definition: SVM.h:233
void set_tube_epsilon(float64_t eps)
Definition: SVM.h:131

SHOGUN Machine Learning Toolbox - Documentation