SHOGUN  6.1.3
MultilabelCLRModel.cpp
Go to the documentation of this file.
1 /*
2  * This software is distributed under BSD 3-clause license (see LICENSE file).
3  *
4  * Copyright(C) 2014 Thoralf Klein
5  * Written(W) 2014 Thoralf Klein
6  * Written(W) 2014 Abinash Panda
7  */
8 
14 
15 using namespace shogun;
16 
19 {
20  init();
21 }
22 
24  CStructuredLabels * labels) : CStructuredModel(features, labels)
25 {
26  init();
27 }
28 
30  int32_t num_labels)
31 {
32  return new CMultilabelSOLabels(num_labels, m_num_classes);
33 }
34 
36 {
37 }
38 
39 void CMultilabelCLRModel::init()
40 {
41  SG_ADD(&m_num_classes, "num_classes", "Number of (binary) class assignment per label",
43  m_num_classes = 0;
44 }
45 
47 {
48  int32_t num_classes = ((CMultilabelSOLabels *)m_labels)->get_num_classes();
49  int32_t feats_dim = ((CDotFeatures *)m_features)->get_dim_feature_space();
50 
51  return feats_dim * (num_classes + 1);
52 }
53 
55  int32_t feat_idx, CStructuredData * y)
56 {
58  psi.zero();
59 
60  int32_t num_classes = ((CMultilabelSOLabels *)m_labels)->get_num_classes();
61  int32_t num_pos_labels = (CSparseMultilabel::obtain_from_generic(y))->
62  get_data().vlen;
63  int32_t num_neg_labels = num_classes - num_pos_labels;
64 
65  // the calibrated label is considered to be the last label
66  SGVector<float64_t> label_coeffs(num_classes + 1);
67  label_coeffs.zero();
68  // the label coefficients would be positive for the relevant/positive
69  // labels (P), negative for irrelevant/negative labels (N) and would be the
70  // difference of number of irrelevant labels and number of revelant labels
71  // for the calibrated/virtual label as
72  // labels_coeff = \sum_{i \in P}{l(i) - l(v)} + \sum_{j \in N}{l(v) - l(j)}
73  // where $v$ is the calibrated/virtual label
74  label_coeffs += CMultilabelSOLabels::to_dense(y, num_classes + 1, 1, -1);
75  label_coeffs[num_classes] = num_neg_labels - num_pos_labels;
76 
77  CDotFeatures * dot_feats = (CDotFeatures *)m_features;
79  int32_t feats_dim = dot_feats->get_dim_feature_space();
80 
81  for (index_t i = 0; i < num_classes + 1; i++)
82  {
83  float64_t coeff = label_coeffs[i];
84 
85  for (index_t j = 0; j < feats_dim; j++)
86  {
87  psi[i * feats_dim + j] = coeff * x[j];
88  }
89  }
90 
91  return psi;
92 }
93 
95 {
98 
99  ASSERT(y1_slabel != NULL);
100  ASSERT(y2_slabel != NULL);
101 
103  return delta_loss(
105  multi_labels->get_num_classes(), 1, 0),
107  multi_labels->get_num_classes(), 1, 0));
108 }
109 
111 {
112  REQUIRE(y1.vlen == y2.vlen, "Size of both the vectors should be same\n");
113 
114  float64_t loss = 0;
115 
116  for (index_t i = 0; i < y1.vlen; i++)
117  {
118  loss += delta_loss(y1[i], y2[i]);
119  }
120 
121  return loss;
122 }
123 
125 {
126  return y1 != y2 ? 1 : 0;
127 }
128 
129 SGVector<int32_t> CMultilabelCLRModel::to_sparse(SGVector<float64_t> dense_vec,
130  float64_t d_true, float64_t d_false)
131 {
132  int32_t size = 0;
133 
134  for (index_t i = 0; i < dense_vec.vlen; i++)
135  {
136  REQUIRE(dense_vec[i] == d_true || dense_vec[i] == d_false,
137  "The values of dense vector should be either (%d) or (%d).\n",
138  d_true, d_false);
139 
140  if (dense_vec[i] == d_true)
141  {
142  size++;
143  }
144  }
145 
146  SGVector<int32_t> sparse_vec(size);
147  index_t j = 0;
148 
149  for (index_t i = 0; i < dense_vec.vlen; i++)
150  {
151  if (dense_vec[i] == d_true)
152  {
153  sparse_vec[j] = i;
154  j++;
155  }
156  }
157 
158  return sparse_vec;
159 }
160 
162  bool const training)
163 {
164  CDotFeatures * dot_feats = (CDotFeatures *)m_features;
165  int32_t feats_dim = dot_feats->get_dim_feature_space();
166 
168 
169  if (training)
170  {
171  m_num_classes = multi_labs->get_num_classes();
172  }
173  else
174  {
175  REQUIRE(m_num_classes > 0, "The model needs to be trained before using "
176  "it for prediction\n");
177  }
178 
179  int32_t dim = get_dim();
180  ASSERT(dim == w.vlen);
181 
182  SGVector<float64_t> plus_minus_one(m_num_classes);
183 
184  if (training)
185  {
186  plus_minus_one.set_const(-1);
187 
189  multi_labs->get_label(feat_idx));
190  SGVector<int32_t> y_true_data = y_true->get_data();
191 
192  for (index_t i = 0; i < y_true_data.vlen; i++)
193  {
194  plus_minus_one[y_true_data[i]] = 1;
195  }
196 
197  SG_UNREF(y_true);
198  }
199  else
200  {
201  plus_minus_one.zero();
202  }
203 
204  float64_t score = 0, calibrated_score = 0;
205 
206  // last label (m_num_class + 1)th label is the calibrated/virtual label
207  calibrated_score = dot_feats->dense_dot(feat_idx, w.vector + m_num_classes * feats_dim,
208  feats_dim);
209 
210  SGVector<float64_t> class_product(m_num_classes);
211 
212  for (index_t i = 0; i < m_num_classes; i++)
213  {
214  score = dot_feats->dense_dot(feat_idx, w.vector + i * feats_dim,
215  feats_dim);
216  class_product[i] = score - calibrated_score;
217  }
218 
219  int32_t count = 0;
220  SGVector<float64_t> y_pred_dense(m_num_classes);
221  y_pred_dense.zero();
222 
223  for (index_t i = 0; i < m_num_classes; i++)
224  {
225  score = class_product[i] - plus_minus_one[i];
226 
227  if (score >= 0)
228  {
229  y_pred_dense[i] = 1;
230  count++;
231  }
232  }
233 
234  SGVector<int32_t> y_pred_sparse = to_sparse(y_pred_dense, 1, 0);
235  ASSERT(count == y_pred_sparse.vlen);
236 
237  CResultSet * ret = new CResultSet();
238  SG_REF(ret);
239  ret->psi_computed = true;
240 
241  CSparseMultilabel * y_pred = new CSparseMultilabel(y_pred_sparse);
242  SG_REF(y_pred);
243 
244  ret->psi_pred = get_joint_feature_vector(feat_idx, y_pred);
245  ret->score = linalg::dot(w, ret->psi_pred);
246  ret->argmax = y_pred;
247 
248  if (training)
249  {
250  ret->delta = CStructuredModel::delta_loss(feat_idx, y_pred);
252  feat_idx, feat_idx);
253  ret->score += (ret->delta - linalg::dot(w, ret->psi_truth));
254  }
255 
256  return ret;
257 }
258 
260  float64_t regularization,
268 {
270 }
271 
SGVector< float64_t > psi_truth
Base class of the labels used in Structured Output (SO) problems.
int32_t index_t
Definition: common.h:72
Class CMultilabelSOLabels used in the application of Structured Output (SO) learning to Multilabel Cl...
virtual float64_t dense_dot(int32_t vec_idx1, const float64_t *vec2, int32_t vec2_len)=0
virtual void init_primal_opt(float64_t regularization, SGMatrix< float64_t > &A, SGVector< float64_t > a, SGMatrix< float64_t > B, SGVector< float64_t > &b, SGVector< float64_t > &lb, SGVector< float64_t > &ub, SGMatrix< float64_t > &C)
virtual SGVector< float64_t > get_joint_feature_vector(int32_t feat_idx, CStructuredData *y)
#define REQUIRE(x,...)
Definition: SGIO.h:181
T dot(const SGVector< T > &a, const SGVector< T > &b)
SGVector< float64_t > get_joint_feature_vector(int32_t feat_idx, int32_t lab_idx)
Features that support dot products among other operations.
Definition: DotFeatures.h:44
#define SG_REF(x)
Definition: SGObject.h:52
virtual int32_t get_dim_feature_space() const =0
#define ASSERT(x)
Definition: SGIO.h:176
double float64_t
Definition: common.h:60
static SGMatrix< T > create_identity_matrix(index_t size, T scale)
float64_t delta_loss(int32_t ytrue_idx, CStructuredData *ypred)
Class CSparseMultilabel to be used in the application of Structured Output (SO) learning to Multilabe...
void set_const(T const_elem)
Definition: SGVector.cpp:199
Class CStructuredModel that represents the application specific model and contains most of the applic...
#define SG_UNREF(x)
Definition: SGObject.h:53
CStructuredLabels * m_labels
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
virtual CStructuredLabels * structured_labels_factory(int32_t num_labels=0)
The class Features is the base class of all feature objects.
Definition: Features.h:69
static SGVector< float64_t > to_dense(CStructuredData *label, int32_t dense_dim, float64_t d_true, float64_t d_false)
CStructuredData * argmax
SGVector< float64_t > get_computed_dot_feature_vector(int32_t num)
SGVector< float64_t > psi_pred
virtual CStructuredData * get_label(int32_t j)
#define SG_ADD(...)
Definition: SGObject.h:93
virtual int32_t get_num_classes() const
virtual CResultSet * argmax(SGVector< float64_t > w, int32_t feat_idx, bool const training=true)
Base class of the components of StructuredLabels.
static CSparseMultilabel * obtain_from_generic(CStructuredData *base_data)
virtual float64_t delta_loss(CStructuredData *y1, CStructuredData *y2)
SGVector< int32_t > get_data() const
index_t vlen
Definition: SGVector.h:571
virtual int32_t get_dim() const

SHOGUN Machine Learning Toolbox - Documentation