SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GMNPSVM.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-2008 Vojtech Franc, xfrancv@cmp.felk.cvut.cz
8  * Copyright (C) 1999-2008 Center for Machine Perception, CTU FEL Prague
9  */
10 
11 #include <shogun/io/SGIO.h>
16 
17 #define INDEX(ROW,COL,DIM) (((COL)*(DIM))+(ROW))
18 #define MINUS_INF INT_MIN
19 #define PLUS_INF INT_MAX
20 #define KDELTA(A,B) (A==B)
21 #define KDELTA4(A1,A2,A3,A4) ((A1==A2)||(A1==A3)||(A1==A4)||(A2==A3)||(A2==A4)||(A3==A4))
22 
23 using namespace shogun;
24 
27 {
28  init();
29 }
30 
33 {
34  init();
35 }
36 
38 {
39  if (m_basealphas != NULL) SG_FREE(m_basealphas);
40 }
41 
42 void
43 CGMNPSVM::init()
44 {
47  "m_basealphas",
48  "Is the basic untransformed alpha.");
49 
51 }
52 
54 {
58 
59  if (data)
60  {
61  if (m_labels->get_num_labels() != data->get_num_vectors())
62  {
63  SG_ERROR("%s::train_machine(): Number of training vectors (%d) does"
64  " not match number of labels (%d)\n", get_name(),
66  }
67  m_kernel->init(data, data);
68  }
69 
70  int32_t num_data = m_labels->get_num_labels();
71  int32_t num_classes = m_multiclass_strategy->get_num_classes();
72  int32_t num_virtual_data= num_data*(num_classes-1);
73 
74  SG_INFO( "%d trainlabels, %d classes\n", num_data, num_classes);
75 
76  float64_t* vector_y = SG_MALLOC(float64_t, num_data);
77  for (int32_t i=0; i<num_data; i++)
78  {
79  vector_y[i] = ((CMulticlassLabels*) m_labels)->get_label(i)+1;
80 
81  }
82 
83  float64_t C = get_C();
84  int32_t tmax = 1000000000;
85  float64_t tolabs = 0;
86  float64_t tolrel = get_epsilon();
87 
88  float64_t reg_const=0;
89  if( C!=0 )
90  reg_const = 1/(2*C);
91 
92 
93  float64_t* alpha = SG_MALLOC(float64_t, num_virtual_data);
94  float64_t* vector_c = SG_MALLOC(float64_t, num_virtual_data);
95  memset(vector_c, 0, num_virtual_data*sizeof(float64_t));
96 
97  float64_t thlb = 10000000000.0;
98  int32_t t = 0;
99  float64_t* History = NULL;
100  int32_t verb = 0;
101 
102  CGMNPLib mnp(vector_y,m_kernel,num_data, num_virtual_data, num_classes, reg_const);
103 
104  mnp.gmnp_imdm(vector_c, num_virtual_data, tmax,
105  tolabs, tolrel, thlb, alpha, &t, &History, verb);
106 
107  /* matrix alpha [num_classes x num_data] */
108  float64_t* all_alphas= SG_MALLOC(float64_t, num_classes*num_data);
109  memset(all_alphas,0,num_classes*num_data*sizeof(float64_t));
110 
111  /* bias vector b [num_classes x 1] */
112  float64_t* all_bs=SG_MALLOC(float64_t, num_classes);
113  memset(all_bs,0,num_classes*sizeof(float64_t));
114 
115  /* compute alpha/b from virt_data */
116  for(int32_t i=0; i < num_classes; i++ )
117  {
118  for(int32_t j=0; j < num_virtual_data; j++ )
119  {
120  int32_t inx1=0;
121  int32_t inx2=0;
122 
123  mnp.get_indices2( &inx1, &inx2, j );
124 
125  all_alphas[(inx1*num_classes)+i] +=
126  alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
127  all_bs[i] += alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
128  }
129  }
130 
131  create_multiclass_svm(num_classes);
132 
133  for (int32_t i=0; i<num_classes; i++)
134  {
135  int32_t num_sv=0;
136  for (int32_t j=0; j<num_data; j++)
137  {
138  if (all_alphas[j*num_classes+i] != 0)
139  num_sv++;
140  }
141  ASSERT(num_sv>0);
142  SG_DEBUG("svm[%d] has %d sv, b=%f\n", i, num_sv, all_bs[i]);
143 
144  CSVM* svm=new CSVM(num_sv);
145 
146  int32_t k=0;
147  for (int32_t j=0; j<num_data; j++)
148  {
149  if (all_alphas[j*num_classes+i] != 0)
150  {
151  svm->set_alpha(k, all_alphas[j*num_classes+i]);
152  svm->set_support_vector(k, j);
153  k++;
154  }
155  }
156 
157  svm->set_bias(all_bs[i]);
158  set_svm(i, svm);
159  }
160 
161  if (m_basealphas != NULL) SG_FREE(m_basealphas);
162  m_basealphas_y = num_classes, m_basealphas_x = num_data;
163  m_basealphas = SG_MALLOC(float64_t, m_basealphas_y*m_basealphas_x);
164  for (index_t i=0; i<m_basealphas_y*m_basealphas_x; i++)
165  m_basealphas[i] = 0.0;
166 
167  for(index_t j=0; j<num_virtual_data; j++)
168  {
169  index_t inx1=0, inx2=0;
170 
171  mnp.get_indices2(&inx1, &inx2, j);
172  m_basealphas[inx1*m_basealphas_y + (inx2-1)] = alpha[j];
173  }
174 
175  SG_FREE(vector_c);
176  SG_FREE(alpha);
177  SG_FREE(all_alphas);
178  SG_FREE(all_bs);
179  SG_FREE(vector_y);
180  SG_FREE(History);
181 
182  return true;
183 }
184 
185 float64_t*
187 {
188  if (y == NULL || x == NULL) return NULL;
189 
190  *y = m_basealphas_y, *x = m_basealphas_x;
191  return m_basealphas;
192 }

SHOGUN Machine Learning Toolbox - Documentation