SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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>
14 
15 #define INDEX(ROW,COL,DIM) (((COL)*(DIM))+(ROW))
16 #define MINUS_INF INT_MIN
17 #define PLUS_INF INT_MAX
18 #define KDELTA(A,B) (A==B)
19 #define KDELTA4(A1,A2,A3,A4) ((A1==A2)||(A1==A3)||(A1==A4)||(A2==A3)||(A2==A4)||(A3==A4))
20 
21 using namespace shogun;
22 
24 : CMultiClassSVM(ONE_VS_REST)
25 {
26  init();
27 }
28 
30 : CMultiClassSVM(ONE_VS_REST, C, k, lab)
31 {
32  init();
33 }
34 
36 {
37  if (m_basealphas != NULL) SG_FREE(m_basealphas);
38 }
39 
40 void
41 CGMNPSVM::init()
42 {
45  "m_basealphas",
46  "Is the basic untransformed alpha.");
47 
49 }
50 
52 {
53  ASSERT(kernel);
55 
56  if (data)
57  {
58  if (data->get_num_vectors() != labels->get_num_labels())
59  {
60  SG_ERROR("Numbert of vectors (%d) does not match number of labels (%d)\n",
62  }
63  kernel->init(data, data);
64  }
65 
66  int32_t num_data = labels->get_num_labels();
67  int32_t num_classes = labels->get_num_classes();
68  int32_t num_virtual_data= num_data*(num_classes-1);
69 
70  SG_INFO( "%d trainlabels, %d classes\n", num_data, num_classes);
71 
72  float64_t* vector_y = SG_MALLOC(float64_t, num_data);
73  for (int32_t i=0; i<num_data; i++)
74  {
75  vector_y[i]= labels->get_label(i)+1;
76 
77  }
78 
79  float64_t C = get_C1();
80  int32_t tmax = 1000000000;
81  float64_t tolabs = 0;
82  float64_t tolrel = epsilon;
83 
84  float64_t reg_const=0;
85  if( C!=0 )
86  reg_const = 1/(2*C);
87 
88 
89  float64_t* alpha = SG_MALLOC(float64_t, num_virtual_data);
90  float64_t* vector_c = SG_MALLOC(float64_t, num_virtual_data);
91  memset(vector_c, 0, num_virtual_data*sizeof(float64_t));
92 
93  float64_t thlb = 10000000000.0;
94  int32_t t = 0;
95  float64_t* History = NULL;
96  int32_t verb = 0;
97 
98  CGMNPLib mnp(vector_y,kernel,num_data, num_virtual_data, num_classes, reg_const);
99 
100  mnp.gmnp_imdm(vector_c, num_virtual_data, tmax,
101  tolabs, tolrel, thlb, alpha, &t, &History, verb);
102 
103  /* matrix alpha [num_classes x num_data] */
104  float64_t* all_alphas= SG_MALLOC(float64_t, num_classes*num_data);
105  memset(all_alphas,0,num_classes*num_data*sizeof(float64_t));
106 
107  /* bias vector b [num_classes x 1] */
108  float64_t* all_bs=SG_MALLOC(float64_t, num_classes);
109  memset(all_bs,0,num_classes*sizeof(float64_t));
110 
111  /* compute alpha/b from virt_data */
112  for(int32_t i=0; i < num_classes; i++ )
113  {
114  for(int32_t j=0; j < num_virtual_data; j++ )
115  {
116  int32_t inx1=0;
117  int32_t inx2=0;
118 
119  mnp.get_indices2( &inx1, &inx2, j );
120 
121  all_alphas[(inx1*num_classes)+i] +=
122  alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
123  all_bs[i] += alpha[j]*(KDELTA(vector_y[inx1],i+1)-KDELTA(i+1,inx2));
124  }
125  }
126 
127  create_multiclass_svm(num_classes);
128 
129  for (int32_t i=0; i<num_classes; i++)
130  {
131  int32_t num_sv=0;
132  for (int32_t j=0; j<num_data; j++)
133  {
134  if (all_alphas[j*num_classes+i] != 0)
135  num_sv++;
136  }
137  ASSERT(num_sv>0);
138  SG_DEBUG("svm[%d] has %d sv, b=%f\n", i, num_sv, all_bs[i]);
139 
140  CSVM* svm=new CSVM(num_sv);
141 
142  int32_t k=0;
143  for (int32_t j=0; j<num_data; j++)
144  {
145  if (all_alphas[j*num_classes+i] != 0)
146  {
147  svm->set_alpha(k, all_alphas[j*num_classes+i]);
148  svm->set_support_vector(k, j);
149  k++;
150  }
151  }
152 
153  svm->set_bias(all_bs[i]);
154  set_svm(i, svm);
155  }
156 
157  if (m_basealphas != NULL) SG_FREE(m_basealphas);
158  m_basealphas_y = num_classes, m_basealphas_x = num_data;
159  m_basealphas = SG_MALLOC(float64_t, m_basealphas_y*m_basealphas_x);
160  for (index_t i=0; i<m_basealphas_y*m_basealphas_x; i++)
161  m_basealphas[i] = 0.0;
162 
163  for(index_t j=0; j<num_virtual_data; j++)
164  {
165  index_t inx1=0, inx2=0;
166 
167  mnp.get_indices2(&inx1, &inx2, j);
168  m_basealphas[inx1*m_basealphas_y + (inx2-1)] = alpha[j];
169  }
170 
171  SG_FREE(vector_c);
172  SG_FREE(alpha);
173  SG_FREE(all_alphas);
174  SG_FREE(all_bs);
175  SG_FREE(vector_y);
176  SG_FREE(History);
177 
178  return true;
179 }
180 
181 float64_t*
183 {
184  if (y == NULL || x == NULL) return NULL;
185 
186  *y = m_basealphas_y, *x = m_basealphas_x;
187  return m_basealphas;
188 }

SHOGUN Machine Learning Toolbox - Documentation