SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MultitaskKernelTreeNormalizer.h
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 2 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010 Christian Widmer
8  * Copyright (C) 2010 Max-Planck-Society
9  */
10 
11 #ifndef _MULTITASKKERNELTREENORMALIZER_H___
12 #define _MULTITASKKERNELTREENORMALIZER_H___
13 
15 #include <shogun/kernel/Kernel.h>
16 #include <algorithm>
17 #include <map>
18 #include <set>
19 #include <deque>
20 #include <vector>
21 
22 namespace shogun
23 {
24 
29 class CNode: public CSGObject
30 {
31 public:
35  {
36  parent = NULL;
37  beta = 1.0;
38  node_id = 0;
39  }
40 
41  virtual ~CNode()
42  {
43  for (size_t i = 0; i < children.size(); i++)
44  delete children[i];
45  }
46 
50  std::set<CNode*> get_path_root()
51  {
52  std::set<CNode*> nodes_on_path = std::set<CNode*>();
53  CNode *node = this;
54  while (node != NULL) {
55  nodes_on_path.insert(node);
56  node = node->parent;
57  }
58  return nodes_on_path;
59  }
60 
64  std::vector<int32_t> get_task_ids_below()
65  {
66 
67  std::vector<int32_t> task_ids;
68  std::deque<CNode*> grey_nodes;
69  grey_nodes.push_back(this);
70 
71  while(grey_nodes.size() > 0)
72  {
73 
74  CNode *current_node = grey_nodes.front();
75  grey_nodes.pop_front();
76 
77  for(int32_t i = 0; i!=int32_t(current_node->children.size()); i++){
78  grey_nodes.push_back(current_node->children[i]);
79  }
80 
81  if(current_node->is_leaf()){
82  task_ids.push_back(current_node->getNode_id());
83  }
84  }
85 
86  return task_ids;
87  }
88 
93  {
94  node->parent = this;
95  this->children.push_back(node);
96  }
97 
99  virtual const char *get_name() const
100  {
101  return "Node";
102  }
103 
105  bool is_leaf()
106  {
107  return children.empty();
108 
109  }
110 
112  int32_t getNode_id() const
113  {
114  return node_id;
115  }
116 
118  void setNode_id(int32_t node_idx)
119  {
120  this->node_id = node_idx;
121  }
122 
125 
126 protected:
127 
130 
132  std::vector<CNode*> children;
133 
135  int32_t node_id;
136 
137 };
138 
139 
144 class CTaxonomy : public CSGObject
145 {
146 
147 public:
148 
152  {
153  root = new CNode();
154  nodes.push_back(root);
155 
156  name2id = std::map<std::string, int32_t>();
157  name2id["root"] = 0;
158  }
159 
160  virtual ~CTaxonomy()
161  {
162  for (size_t i = 0; i < nodes.size(); i++)
163  delete nodes[i];
164  nodes.clear();
165  name2id.clear();
166  task_histogram.clear();
167  }
168 
173  CNode* get_node(int32_t task_id) {
174  return nodes[task_id];
175  }
176 
181  {
182  nodes[0]->beta = beta;
183  }
184 
190  CNode* add_node(std::string parent_name, std::string child_name, float64_t beta)
191  {
192  if (child_name=="") SG_ERROR("child_name empty")
193  if (parent_name=="") SG_ERROR("parent_name empty")
194 
195 
196  CNode* child_node = new CNode();
197 
198  child_node->beta = beta;
199 
200  nodes.push_back(child_node);
201  int32_t id = nodes.size()-1;
202 
203  name2id[child_name] = id;
204 
205  child_node->setNode_id(id);
206 
207 
208  //create edge
209  CNode* parent = nodes[name2id[parent_name]];
210 
211  parent->add_child(child_node);
212 
213  return child_node;
214  }
215 
220  int32_t get_id(std::string name) {
221  return name2id[name];
222  }
223 
229  std::set<CNode*> intersect_root_path(CNode* node_lhs, CNode* node_rhs)
230  {
231 
232  std::set<CNode*> root_path_lhs = node_lhs->get_path_root();
233  std::set<CNode*> root_path_rhs = node_rhs->get_path_root();
234 
235  std::set<CNode*> intersection;
236 
237  std::set_intersection(root_path_lhs.begin(), root_path_lhs.end(),
238  root_path_rhs.begin(), root_path_rhs.end(),
239  std::inserter(intersection, intersection.end()));
240 
241  return intersection;
242 
243  }
244 
250  float64_t compute_node_similarity(int32_t task_lhs, int32_t task_rhs)
251  {
252 
253  CNode* node_lhs = get_node(task_lhs);
254  CNode* node_rhs = get_node(task_rhs);
255 
256  // compute intersection of paths to root
257  std::set<CNode*> intersection = intersect_root_path(node_lhs, node_rhs);
258 
259  // sum up weights
260  float64_t gamma = 0;
261  for (std::set<CNode*>::const_iterator p = intersection.begin(); p != intersection.end(); ++p) {
262 
263  gamma += (*p)->beta;
264  }
265 
266  return gamma;
267 
268  }
269 
273  void update_task_histogram(std::vector<int32_t> task_vector_lhs) {
274 
275  //empty map
276  task_histogram.clear();
277 
278 
279  //fill map with zeros
280  for (std::vector<int32_t>::const_iterator it=task_vector_lhs.begin(); it!=task_vector_lhs.end(); it++)
281  {
282  task_histogram[*it] = 0.0;
283  }
284 
285  //fill map
286  for (std::vector<int32_t>::const_iterator it=task_vector_lhs.begin(); it!=task_vector_lhs.end(); it++)
287  {
288  task_histogram[*it] += 1.0;
289  }
290 
291  //compute fractions
292  for (std::map<int32_t, float64_t>::const_iterator it=task_histogram.begin(); it!=task_histogram.end(); it++)
293  {
294  task_histogram[it->first] = task_histogram[it->first] / float64_t(task_vector_lhs.size());
295  }
296 
297  }
298 
300  int32_t get_num_nodes()
301  {
302  return (int32_t)(nodes.size());
303  }
304 
306  int32_t get_num_leaves()
307  {
308  int32_t num_leaves = 0;
309 
310  for (int32_t i=0; i!=get_num_nodes(); i++)
311  {
312  if (get_node(i)->is_leaf()==true)
313  {
314  num_leaves++;
315  }
316  }
317 
318  return num_leaves;
319  }
320 
323  {
324  CNode* node = get_node(idx);
325  return node->beta;
326  }
327 
332  void set_node_weight(int32_t idx, float64_t weight)
333  {
334  CNode* node = get_node(idx);
335  node->beta = weight;
336  }
337 
339  virtual const char* get_name() const
340  {
341  return "Taxonomy";
342  }
343 
345  std::map<std::string, int32_t> get_name2id() {
346  return name2id;
347  }
348 
354  int32_t get_id_by_name(std::string name)
355  {
356  return name2id[name];
357  }
358 
359 
360 protected:
361 
365  std::map<std::string, int32_t> name2id;
367  std::vector<CNode*> nodes;
369  std::map<int32_t, float64_t> task_histogram;
370 
371 };
372 
377 {
378 
379 public:
380 
384  {
385  }
386 
393  CMultitaskKernelTreeNormalizer(std::vector<std::string> task_lhs,
394  std::vector<std::string> task_rhs,
396  {
397 
398  taxonomy = tax;
399  set_task_vector_lhs(task_lhs);
400  set_task_vector_rhs(task_rhs);
401 
403 
404  dependency_matrix = std::vector<float64_t>(num_nodes * num_nodes);
405 
406  update_cache();
407  }
408 
409 
412  {
413  }
414 
415 
418  {
419 
420 
421  for (int32_t i=0; i!=num_nodes; i++)
422  {
423  for (int32_t j=0; j!=num_nodes; j++)
424  {
425 
426  float64_t similarity = taxonomy.compute_node_similarity(i, j);
427  set_node_similarity(i,j,similarity);
428 
429  }
430 
431  }
432  }
433 
434 
435 
441  virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs)
442  {
443  //lookup tasks
444  int32_t task_idx_lhs = task_vector_lhs[idx_lhs];
445  int32_t task_idx_rhs = task_vector_rhs[idx_rhs];
446 
447  //lookup similarity
448  float64_t task_similarity = get_node_similarity(task_idx_lhs, task_idx_rhs);
449  //float64_t task_similarity = taxonomy.compute_node_similarity(task_idx_lhs, task_idx_rhs);
450 
451  //take task similarity into account
452  float64_t similarity = (value/scale) * task_similarity;
453 
454 
455  return similarity;
456  }
457 
462  virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs)
463  {
464  SG_ERROR("normalize_lhs not implemented")
465  return 0;
466  }
467 
472  virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs)
473  {
474  SG_ERROR("normalize_rhs not implemented")
475  return 0;
476  }
477 
478 
480  void set_task_vector_lhs(std::vector<std::string> vec)
481  {
482 
483  task_vector_lhs.clear();
484 
485  for (int32_t i = 0; i != (int32_t)(vec.size()); ++i)
486  {
487  task_vector_lhs.push_back(taxonomy.get_id(vec[i]));
488  }
489 
490  //update task histogram
492 
493  }
494 
496  void set_task_vector_rhs(std::vector<std::string> vec)
497  {
498 
499  task_vector_rhs.clear();
500 
501  for (int32_t i = 0; i != (int32_t)(vec.size()); ++i)
502  {
503  task_vector_rhs.push_back(taxonomy.get_id(vec[i]));
504  }
505 
506  }
507 
509  void set_task_vector(std::vector<std::string> vec)
510  {
511  set_task_vector_lhs(vec);
512  set_task_vector_rhs(vec);
513  }
514 
516  int32_t get_num_betas()
517  {
518 
519  return taxonomy.get_num_nodes();
520 
521  }
522 
526  float64_t get_beta(int32_t idx)
527  {
528 
529  return taxonomy.get_node_weight(idx);
530 
531  }
532 
536  void set_beta(int32_t idx, float64_t weight)
537  {
538 
539  taxonomy.set_node_weight(idx, weight);
540 
541  update_cache();
542 
543  }
544 
545 
551  float64_t get_node_similarity(int32_t node_lhs, int32_t node_rhs)
552  {
553 
554  ASSERT(node_lhs < num_nodes && node_lhs >= 0)
555  ASSERT(node_rhs < num_nodes && node_rhs >= 0)
556 
557  return dependency_matrix[node_lhs * num_nodes + node_rhs];
558 
559  }
560 
566  void set_node_similarity(int32_t node_lhs, int32_t node_rhs,
567  float64_t similarity)
568  {
569 
570  ASSERT(node_lhs < num_nodes && node_lhs >= 0)
571  ASSERT(node_rhs < num_nodes && node_rhs >= 0)
572 
573  dependency_matrix[node_lhs * num_nodes + node_rhs] = similarity;
574 
575  }
576 
578  virtual const char* get_name() const
579  {
580  return "MultitaskKernelTreeNormalizer";
581  }
582 
587  {
588  return dynamic_cast<CMultitaskKernelTreeNormalizer*>(n);
589  }
590 
591 protected:
594 
596  int32_t num_nodes;
597 
599  std::vector<int32_t> task_vector_lhs;
600 
602  std::vector<int32_t> task_vector_rhs;
603 
605  std::vector<float64_t> dependency_matrix;
606 };
607 }
608 #endif

SHOGUN Machine Learning Toolbox - Documentation