SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ShareBoost.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) 2012 Chiyuan Zhang
8  * Copyright (C) 2012 Chiyuan Zhang
9  */
10 
11 #include <algorithm>
12 
13 #include <shogun/lib/Time.h>
19 
20 using namespace shogun;
21 
23  :CLinearMulticlassMachine(), m_nonzero_feas(0)
24 {
25  init_sb_params();
26 }
27 
28 CShareBoost::CShareBoost(CDenseFeatures<float64_t> *features, CMulticlassLabels *labs, int32_t num_nonzero_feas)
29  :CLinearMulticlassMachine(new CMulticlassOneVsRestStrategy(), features, NULL, labs), m_nonzero_feas(num_nonzero_feas)
30 {
31  init_sb_params();
32 }
33 
34 void CShareBoost::init_sb_params()
35 {
36  SG_ADD(&m_nonzero_feas, "m_nonzero_feas", "Number of non-zero features", MS_NOT_AVAILABLE);
37 }
38 
40 {
41  return m_activeset.clone();
42 }
43 
45 {
47  if (data)
48  set_features(data);
49 
50  if (m_features == NULL)
51  SG_ERROR("No features given for training\n")
52  if (m_labels == NULL)
53  SG_ERROR("No labels given for training\n")
54 
55  if (m_nonzero_feas <= 0)
56  SG_ERROR("Set a valid (> 0) number of non-zero features to seek before training\n")
57  if (m_nonzero_feas > fea->get_num_features())
58  SG_ERROR("Number of non-zero features (%d) cannot be larger than number of features (%d) in the data\n",
59  m_nonzero_feas, fea->get_num_features())
60 
61  m_fea = fea->get_feature_matrix();
63  m_rho_norm = SGVector<float64_t>(m_fea.num_cols);
65  m_pred.zero();
66 
67  m_activeset = SGVector<int32_t>(m_fea.num_rows);
68  m_activeset.vlen = 0;
69 
71  for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
73 
74  CTime *timer = new CTime();
75 
76  float64_t t_compute_pred = 0; // t of 1st round is 0, since no pred to compute
77  for (int32_t t=0; t < m_nonzero_feas; ++t)
78  {
79  timer->start();
80  compute_rho();
81  int32_t i_fea = choose_feature();
82  m_activeset.vector[m_activeset.vlen] = i_fea;
83  m_activeset.vlen += 1;
84  float64_t t_choose_feature = timer->cur_time_diff();
85  timer->start();
86  optimize_coefficients();
87  float64_t t_optimize = timer->cur_time_diff();
88 
89  SG_SDEBUG(" SB[round %03d]: (%8.4f + %8.4f) sec.\n", t,
90  t_compute_pred + t_choose_feature, t_optimize);
91 
92  timer->start();
93  compute_pred();
94  t_compute_pred = timer->cur_time_diff();
95  }
96 
97  SG_UNREF(timer);
98 
99  // release memory
100  m_fea = SGMatrix<float64_t>();
101  m_rho = SGMatrix<float64_t>();
102  m_rho_norm = SGVector<float64_t>();
103  m_pred = SGMatrix<float64_t>();
104 
105  return true;
106 }
107 
108 void CShareBoost::compute_pred()
109 {
111  CDenseSubsetFeatures<float64_t> *subset_fea = new CDenseSubsetFeatures<float64_t>(fea, m_activeset);
112  SG_REF(subset_fea);
113  for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
114  {
115  CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
116  CRegressionLabels *lab = machine->apply_regression(subset_fea);
117  SGVector<float64_t> lab_raw = lab->get_labels();
118  std::copy(lab_raw.vector, lab_raw.vector + lab_raw.vlen, m_pred.get_column_vector(i));
119  SG_UNREF(machine);
120  SG_UNREF(lab);
121  }
122  SG_UNREF(subset_fea);
123 }
124 
125 void CShareBoost::compute_pred(const float64_t *W)
126 {
127  int32_t w_len = m_activeset.vlen;
128 
129  for (int32_t i=0; i < m_multiclass_strategy->get_num_classes(); ++i)
130  {
131  CLinearMachine *machine = dynamic_cast<CLinearMachine *>(m_machines->get_element(i));
132  SGVector<float64_t> w(w_len);
133  std::copy(W + i*w_len, W + (i+1)*w_len, w.vector);
134  machine->set_w(w);
135  SG_UNREF(machine);
136  }
137  compute_pred();
138 }
139 
140 void CShareBoost::compute_rho()
141 {
142  CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
143  for (int32_t i=0; i < m_rho.num_rows; ++i)
144  { // i loop classes
145  for (int32_t j=0; j < m_rho.num_cols; ++j)
146  { // j loop samples
147  int32_t label = lab->get_int_label(j);
148 
149  m_rho(i,j) = CMath::exp((label == i) - m_pred(j, label) + m_pred(j, i));
150  }
151  }
152 
153  // normalize
154  for (int32_t j=0; j < m_rho.num_cols; ++j)
155  {
156  m_rho_norm[j] = 0;
157  for (int32_t i=0; i < m_rho.num_rows; ++i)
158  m_rho_norm[j] += m_rho(i,j);
159  }
160 }
161 
162 int32_t CShareBoost::choose_feature()
163 {
164  SGVector<float64_t> l1norm(m_fea.num_rows);
165  for (int32_t j=0; j < m_fea.num_rows; ++j)
166  {
167  if (std::find(&m_activeset[0], &m_activeset[m_activeset.vlen], j) !=
168  &m_activeset[m_activeset.vlen])
169  {
170  l1norm[j] = 0;
171  }
172  else
173  {
174  l1norm[j] = 0;
175  CMulticlassLabels *lab = dynamic_cast<CMulticlassLabels *>(m_labels);
176  for (int32_t k=0; k < m_multiclass_strategy->get_num_classes(); ++k)
177  {
178  float64_t abssum = 0;
179  for (int32_t ii=0; ii < m_fea.num_cols; ++ii)
180  {
181  abssum += m_fea(j, ii)*(m_rho(k, ii)/m_rho_norm[ii] -
182  (j == lab->get_int_label(ii)));
183  }
184  l1norm[j] += CMath::abs(abssum);
185  }
186  l1norm[j] /= m_fea.num_cols;
187  }
188  }
189 
190  return CMath::arg_max(l1norm.vector, 1, l1norm.vlen);
191 }
192 
193 void CShareBoost::optimize_coefficients()
194 {
195  ShareBoostOptimizer optimizer(this, false);
196  optimizer.optimize();
197 }
198 
200 {
201  CDenseFeatures<float64_t> *fea = dynamic_cast<CDenseFeatures<float64_t> *>(f);
202  if (fea == NULL)
203  SG_ERROR("Require DenseFeatures<float64_t>\n")
205 }
Class Time that implements a stopwatch based on either cpu time or wall clock time.
Definition: Time.h:47
SGVector< int32_t > get_activeset()
Definition: ShareBoost.cpp:39
Real Labels are real-valued labels.
static int32_t arg_max(T *vec, int32_t inc, int32_t len, T *maxv_ptr=NULL)
Definition: Math.h:262
virtual CRegressionLabels * apply_regression(CFeatures *data=NULL)
int32_t get_num_features() const
virtual void set_w(const SGVector< float64_t > src_w)
SGMatrix< ST > get_feature_matrix()
void set_features(CFeatures *f)
Definition: ShareBoost.cpp:199
CLabels * m_labels
Definition: Machine.h:361
#define SG_ERROR(...)
Definition: SGIO.h:129
index_t num_cols
Definition: SGMatrix.h:376
#define SG_REF(x)
Definition: SGObject.h:54
index_t num_rows
Definition: SGMatrix.h:374
SGVector< float64_t > get_labels()
Definition: DenseLabels.cpp:82
Multiclass Labels for multi-class classification.
float64_t cur_time_diff(bool verbose=false)
Definition: Time.cpp:68
index_t vlen
Definition: SGVector.h:494
generic linear multiclass machine
CMulticlassStrategy * m_multiclass_strategy
int32_t get_int_label(int32_t idx)
double float64_t
Definition: common.h:50
float64_t start(bool verbose=false)
Definition: Time.cpp:59
T * get_column_vector(index_t col) const
Definition: SGMatrix.h:113
Class LinearMachine is a generic interface for all kinds of linear machines like classifiers.
Definition: LinearMachine.h:63
#define SG_UNREF(x)
Definition: SGObject.h:55
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
#define SG_SDEBUG(...)
Definition: SGIO.h:168
virtual bool train_machine(CFeatures *data=NULL)
Definition: ShareBoost.cpp:44
The class Features is the base class of all feature objects.
Definition: Features.h:68
static float64_t exp(float64_t x)
Definition: Math.h:621
SGVector< T > clone() const
Definition: SGVector.cpp:207
CSGObject * get_element(int32_t index) const
multiclass one vs rest strategy used to train generic multiclass machines for K-class problems with b...
#define SG_ADD(...)
Definition: SGObject.h:84
static T abs(T a)
Definition: Math.h:179

SHOGUN Machine Learning Toolbox - Documentation