SHOGUN  6.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
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()), solver_type(st)
20 {
21 }
22 
24 : CMulticlassSVM(new CMulticlassOneVsOneStrategy(), C, k, lab), solver_type(LIBSVM_C_SVC)
25 {
26 }
27 
29 {
30 }
31 
32 void CMulticlassLibSVM::register_params()
33 {
34  SG_ADD((machine_int_t*) &solver_type, "libsvm_solver_type", "LibSVM solver type", MS_NOT_AVAILABLE);
35 }
36 
38 {
39  svm_problem problem;
40  svm_parameter param;
41  struct svm_model* model = nullptr;
42 
43  struct svm_node* x_space;
44 
45  problem = svm_problem();
46 
49  int32_t num_classes = m_multiclass_strategy->get_num_classes();
50  problem.l=m_labels->get_num_labels();
51  SG_INFO("%d trainlabels, %d classes\n", problem.l, num_classes)
52 
53 
54  if (data)
55  {
56  if (m_labels->get_num_labels() != data->get_num_vectors())
57  {
58  SG_ERROR("Number of training vectors does not match number of "
59  "labels\n");
60  }
61  m_kernel->init(data, data);
62  }
63 
64  problem.y=SG_MALLOC(float64_t, problem.l);
65  problem.x=SG_MALLOC(struct svm_node*, problem.l);
66  problem.pv=SG_MALLOC(float64_t, problem.l);
67  problem.C=SG_MALLOC(float64_t, problem.l);
68 
69  x_space=SG_MALLOC(struct svm_node, 2*problem.l);
70 
71  for (int32_t i=0; i<problem.l; i++)
72  {
73  problem.pv[i]=-1.0;
74  problem.y[i]=((CMulticlassLabels*) m_labels)->get_label(i);
75  problem.x[i]=&x_space[2*i];
76  x_space[2*i].index=i;
77  x_space[2*i+1].index=-1;
78  }
79 
81 
82  param.svm_type=solver_type; // C SVM or NU_SVM
83  param.kernel_type = LINEAR;
84  param.degree = 3;
85  param.gamma = 0; // 1/k
86  param.coef0 = 0;
87  param.nu = get_nu(); // Nu
88  param.kernel=m_kernel;
90  param.max_train_time = m_max_train_time;
91  param.C = get_C();
92  param.eps = get_epsilon();
93  param.p = 0.1;
94  param.shrinking = 1;
95  param.nr_weight = 0;
96  param.weight_label = NULL;
97  param.weight = NULL;
98  param.use_bias = svm_proto()->get_bias_enabled();
99 
100  const char* error_msg = svm_check_parameter(&problem,&param);
101 
102  if(error_msg)
103  SG_ERROR("Error: %s\n",error_msg)
104 
105  model = svm_train(&problem, &param);
106 
107  if (model)
108  {
109  if (model->nr_class!=num_classes)
110  {
111  SG_ERROR("LibSVM model->nr_class=%d while num_classes=%d\n",
112  model->nr_class, num_classes);
113  }
114  ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef))
115  create_multiclass_svm(num_classes);
116 
117  int32_t* offsets=SG_MALLOC(int32_t, num_classes);
118  offsets[0]=0;
119 
120  for (int32_t i=1; i<num_classes; i++)
121  offsets[i] = offsets[i-1]+model->nSV[i-1];
122 
123  int32_t s=0;
124  for (int32_t i=0; i<num_classes; i++)
125  {
126  for (int32_t j=i+1; j<num_classes; j++)
127  {
128  int32_t k, l;
129 
130  float64_t sgn=1;
131  if (model->label[i]>model->label[j])
132  sgn=-1;
133 
134  int32_t num_sv=model->nSV[i]+model->nSV[j];
135  float64_t bias=-model->rho[s];
136 
137  ASSERT(num_sv>0)
138  ASSERT(model->sv_coef[i] && model->sv_coef[j-1])
139 
140  CSVM* svm=new CSVM(num_sv);
141 
142  svm->set_bias(sgn*bias);
143 
144  int32_t sv_idx=0;
145  for (k=0; k<model->nSV[i]; 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[i]+k]->index);
150  svm->set_alpha(sv_idx, sgn*model->sv_coef[j-1][offsets[i]+k]);
151  sv_idx++;
152  }
153 
154  for (k=0; k<model->nSV[j]; k++)
155  {
156  SG_DEBUG("setting SV[%d] to %d\n", sv_idx,
157  model->SV[offsets[i]+k]->index);
158  svm->set_support_vector(sv_idx, model->SV[offsets[j]+k]->index);
159  svm->set_alpha(sv_idx, sgn*model->sv_coef[i][offsets[j]+k]);
160  sv_idx++;
161  }
162 
163  int32_t idx=0;
164 
165  if (num_classes > 3)
166  {
167  if (sgn>0)
168  {
169  for (k=0; k<model->label[i]; k++)
170  idx+=num_classes-k-1;
171 
172  for (l=model->label[i]+1; l<model->label[j]; l++)
173  idx++;
174  }
175  else
176  {
177  for (k=0; k<model->label[j]; k++)
178  idx+=num_classes-k-1;
179 
180  for (l=model->label[j]+1; l<model->label[i]; l++)
181  idx++;
182  }
183  }
184  else if (num_classes == 3)
185  {
186  idx = model->label[j]+model->label[i] - 1;
187  }
188  else if (num_classes == 2)
189  {
190  idx = i;
191  }
192 //
193 // if (sgn>0)
194 // idx=((num_classes-1)*model->label[i]+model->label[j])/2;
195 // else
196 // idx=((num_classes-1)*model->label[j]+model->label[i])/2;
197 //
198  SG_DEBUG("svm[%d] has %d sv (total: %d), b=%f "
199  "label:(%d,%d) -> svm[%d]\n",
200  s, num_sv, model->l, bias, model->label[i],
201  model->label[j], idx);
202 
203  REQUIRE(set_svm(idx, svm),"SVM set failed")
204  s++;
205  }
206  }
207 
208  set_objective(model->objective);
209 
210  SG_FREE(offsets);
211  SG_FREE(problem.x);
212  SG_FREE(problem.y);
213  SG_FREE(x_space);
214  SG_FREE(problem.pv);
215  SG_FREE(problem.C);
216 
217  svm_destroy_model(model);
218  model=NULL;
219 
220  return true;
221  }
222  else
223  return false;
224 }
225 
virtual bool init(CFeatures *lhs, CFeatures *rhs)
Definition: Kernel.cpp:96
#define SG_INFO(...)
Definition: SGIO.h:117
virtual ELabelType get_label_type() const =0
multiclass one vs one strategy used to train generic multiclass machines for K-class problems with bu...
The class Labels models labels, i.e. class assignments of objects.
Definition: Labels.h:43
virtual int32_t get_num_labels() const =0
multi-class labels 0,1,...
Definition: LabelTypes.h:20
virtual int32_t get_num_vectors() const =0
float64_t m_max_train_time
Definition: Machine.h:362
CLabels * m_labels
Definition: Machine.h:365
#define SG_ERROR(...)
Definition: SGIO.h:128
#define REQUIRE(x,...)
Definition: SGIO.h:205
int32_t cache_size
cache_size in MB
LIBSVM_SOLVER_TYPE solver_type
Multiclass Labels for multi-class classification.
#define ASSERT(x)
Definition: SGIO.h:200
class MultiClassSVM
Definition: MulticlassSVM.h:28
void set_objective(float64_t v)
void set_bias(float64_t bias)
CMulticlassStrategy * m_multiclass_strategy
double float64_t
Definition: common.h:60
bool set_alpha(int32_t idx, float64_t val)
bool set_support_vector(int32_t idx, int32_t val)
#define SG_DEBUG(...)
Definition: SGIO.h:106
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
int machine_int_t
Definition: common.h:69
The class Features is the base class of all feature objects.
Definition: Features.h:68
bool create_multiclass_svm(int32_t num_classes)
A generic Support Vector Machine Interface.
Definition: SVM.h:49
The Kernel base class.
virtual bool train_machine(CFeatures *data=NULL)
int32_t get_cache_size()
bool set_svm(int32_t num, CSVM *svm)
#define SG_ADD(...)
Definition: SGObject.h:94
CMulticlassLibSVM(LIBSVM_SOLVER_TYPE st=LIBSVM_C_SVC)

SHOGUN Machine Learning Toolbox - Documentation