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

SHOGUN Machine Learning Toolbox - Documentation