SHOGUN  3.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MulticlassLibSVM.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 
14 #include <shogun/io/SGIO.h>
15 
16 using namespace shogun;
17 
19 : CMulticlassSVM(new CMulticlassOneVsOneStrategy()), model(NULL), solver_type(st)
20 {
21 }
22 
24 : CMulticlassSVM(new CMulticlassOneVsOneStrategy(), C, k, lab), model(NULL), solver_type(LIBSVM_C_SVC)
25 {
26 }
27 
29 {
30 }
31 
33 {
34  struct svm_node* x_space;
35 
36  problem = svm_problem();
37 
40  int32_t num_classes = m_multiclass_strategy->get_num_classes();
42  SG_INFO("%d trainlabels, %d classes\n", problem.l, num_classes)
43 
44 
45  if (data)
46  {
47  if (m_labels->get_num_labels() != data->get_num_vectors())
48  {
49  SG_ERROR("Number of training vectors does not match number of "
50  "labels\n");
51  }
52  m_kernel->init(data, data);
53  }
54 
55  problem.y=SG_MALLOC(float64_t, problem.l);
56  problem.x=SG_MALLOC(struct svm_node*, problem.l);
57  problem.pv=SG_MALLOC(float64_t, problem.l);
58  problem.C=SG_MALLOC(float64_t, problem.l);
59 
60  x_space=SG_MALLOC(struct svm_node, 2*problem.l);
61 
62  for (int32_t i=0; i<problem.l; i++)
63  {
64  problem.pv[i]=-1.0;
65  problem.y[i]=((CMulticlassLabels*) m_labels)->get_label(i);
66  problem.x[i]=&x_space[2*i];
67  x_space[2*i].index=i;
68  x_space[2*i+1].index=-1;
69  }
70 
72 
73  param.svm_type=solver_type; // C SVM or NU_SVM
74  param.kernel_type = LINEAR;
75  param.degree = 3;
76  param.gamma = 0; // 1/k
77  param.coef0 = 0;
78  param.nu = get_nu(); // Nu
79  param.kernel=m_kernel;
80  param.cache_size = m_kernel->get_cache_size();
81  param.max_train_time = m_max_train_time;
82  param.C = get_C();
83  param.eps = get_epsilon();
84  param.p = 0.1;
85  param.shrinking = 1;
86  param.nr_weight = 0;
87  param.weight_label = NULL;
88  param.weight = NULL;
89  param.use_bias = svm_proto()->get_bias_enabled();
90 
91  const char* error_msg = svm_check_parameter(&problem,&param);
92 
93  if(error_msg)
94  SG_ERROR("Error: %s\n",error_msg)
95 
96  model = svm_train(&problem, &param);
97 
98  if (model)
99  {
100  if (model->nr_class!=num_classes)
101  {
102  SG_ERROR("LibSVM model->nr_class=%d while num_classes=%d\n",
103  model->nr_class, num_classes);
104  }
105  ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef))
106  create_multiclass_svm(num_classes);
107 
108  int32_t* offsets=SG_MALLOC(int32_t, num_classes);
109  offsets[0]=0;
110 
111  for (int32_t i=1; i<num_classes; i++)
112  offsets[i] = offsets[i-1]+model->nSV[i-1];
113 
114  int32_t s=0;
115  for (int32_t i=0; i<num_classes; i++)
116  {
117  for (int32_t j=i+1; j<num_classes; j++)
118  {
119  int32_t k, l;
120 
121  float64_t sgn=1;
122  if (model->label[i]>model->label[j])
123  sgn=-1;
124 
125  int32_t num_sv=model->nSV[i]+model->nSV[j];
126  float64_t bias=-model->rho[s];
127 
128  ASSERT(num_sv>0)
129  ASSERT(model->sv_coef[i] && model->sv_coef[j-1])
130 
131  CSVM* svm=new CSVM(num_sv);
132 
133  svm->set_bias(sgn*bias);
134 
135  int32_t sv_idx=0;
136  for (k=0; k<model->nSV[i]; k++)
137  {
138  SG_DEBUG("setting SV[%d] to %d\n", sv_idx,
139  model->SV[offsets[i]+k]->index);
140  svm->set_support_vector(sv_idx, model->SV[offsets[i]+k]->index);
141  svm->set_alpha(sv_idx, sgn*model->sv_coef[j-1][offsets[i]+k]);
142  sv_idx++;
143  }
144 
145  for (k=0; k<model->nSV[j]; k++)
146  {
147  SG_DEBUG("setting SV[%d] to %d\n", sv_idx,
148  model->SV[offsets[i]+k]->index);
149  svm->set_support_vector(sv_idx, model->SV[offsets[j]+k]->index);
150  svm->set_alpha(sv_idx, sgn*model->sv_coef[i][offsets[j]+k]);
151  sv_idx++;
152  }
153 
154  int32_t idx=0;
155 
156  if (num_classes > 3)
157  {
158  if (sgn>0)
159  {
160  for (k=0; k<model->label[i]; k++)
161  idx+=num_classes-k-1;
162 
163  for (l=model->label[i]+1; l<model->label[j]; l++)
164  idx++;
165  }
166  else
167  {
168  for (k=0; k<model->label[j]; k++)
169  idx+=num_classes-k-1;
170 
171  for (l=model->label[j]+1; l<model->label[i]; l++)
172  idx++;
173  }
174  }
175  else if (num_classes == 3)
176  {
177  idx = model->label[j]+model->label[i] - 1;
178  }
179  else if (num_classes == 2)
180  {
181  idx = i;
182  }
183 //
184 // if (sgn>0)
185 // idx=((num_classes-1)*model->label[i]+model->label[j])/2;
186 // else
187 // idx=((num_classes-1)*model->label[j]+model->label[i])/2;
188 //
189  SG_DEBUG("svm[%d] has %d sv (total: %d), b=%f "
190  "label:(%d,%d) -> svm[%d]\n",
191  s, num_sv, model->l, bias, model->label[i],
192  model->label[j], idx);
193 
194  REQUIRE(set_svm(idx, svm),"SVM set failed")
195  s++;
196  }
197  }
198 
199  set_objective(model->objective);
200 
201  SG_FREE(offsets);
202  SG_FREE(problem.x);
203  SG_FREE(problem.y);
204  SG_FREE(x_space);
205  SG_FREE(problem.pv);
206  SG_FREE(problem.C);
207 
208  svm_destroy_model(model);
209  model=NULL;
210 
211  return true;
212  }
213  else
214  return false;
215 }
216 

SHOGUN Machine Learning Toolbox - Documentation