SHOGUN
v1.1.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2010 Christian Widmer 00008 * Copyright (C) 2010 Max-Planck-Society 00009 */ 00010 00011 #ifndef _MULTITASKKERNELMASKNORMALIZER_H___ 00012 #define _MULTITASKKERNELMASKNORMALIZER_H___ 00013 00014 #include <shogun/kernel/KernelNormalizer.h> 00015 #include <shogun/kernel/Kernel.h> 00016 #include <set> 00017 #include <string> 00018 00019 namespace shogun 00020 { 00021 00022 00033 class CMultitaskKernelMaskNormalizer: public CKernelNormalizer 00034 { 00035 00036 public: 00037 00040 CMultitaskKernelMaskNormalizer() : CKernelNormalizer(), 00041 scale(1.0), normalization_constant(1.0) 00042 { 00043 } 00044 00051 CMultitaskKernelMaskNormalizer(std::vector<int32_t> task_lhs, 00052 std::vector<int32_t> task_rhs, 00053 std::vector<int32_t> active_tasks_vec) 00054 : CKernelNormalizer(), scale(1.0), normalization_constant(1.0) 00055 { 00056 00057 00058 set_task_vector_lhs(task_lhs); 00059 set_task_vector_rhs(task_rhs); 00060 00061 // set active tasks 00062 for (int32_t i = 0; i != (int32_t)(active_tasks_vec.size()); ++i) 00063 { 00064 active_tasks.insert(active_tasks_vec[i]); 00065 } 00066 00067 } 00068 00069 00071 virtual ~CMultitaskKernelMaskNormalizer() 00072 { 00073 } 00074 00077 virtual bool init(CKernel* k) 00078 { 00079 ASSERT(k); 00080 int32_t num_lhs = k->get_num_vec_lhs(); 00081 int32_t num_rhs = k->get_num_vec_rhs(); 00082 ASSERT(num_lhs>0); 00083 ASSERT(num_rhs>0); 00084 00085 00086 //same as first-element normalizer 00087 CFeatures* old_lhs=k->lhs; 00088 CFeatures* old_rhs=k->rhs; 00089 k->lhs=old_lhs; 00090 k->rhs=old_lhs; 00091 00092 if (std::string(k->get_name()) == "WeightedDegree") { 00093 SG_INFO("using first-element normalization\n"); 00094 scale=k->compute(0, 0); 00095 } else { 00096 SG_INFO("no inner normalization for non-WDK kernel\n"); 00097 scale=1.0; 00098 } 00099 00100 k->lhs=old_lhs; 00101 k->rhs=old_rhs; 00102 00103 00104 return true; 00105 } 00106 00107 00108 00114 inline virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00115 { 00116 00117 //lookup tasks 00118 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00119 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00120 00121 //lookup similarity 00122 float64_t task_similarity = get_similarity(task_idx_lhs, task_idx_rhs); 00123 00124 //take task similarity into account 00125 float64_t similarity = (value/scale) * task_similarity; 00126 00127 00128 return similarity; 00129 00130 } 00131 00136 inline virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00137 { 00138 SG_ERROR("normalize_lhs not implemented"); 00139 return 0; 00140 } 00141 00146 inline virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00147 { 00148 SG_ERROR("normalize_rhs not implemented"); 00149 return 0; 00150 } 00151 00153 std::vector<int32_t> get_task_vector_lhs() const 00154 { 00155 return task_vector_lhs; 00156 } 00157 00158 00160 void set_task_vector_lhs(std::vector<int32_t> vec) 00161 { 00162 00163 task_vector_lhs.clear(); 00164 00165 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00166 { 00167 task_vector_lhs.push_back(vec[i]); 00168 } 00169 00170 } 00171 00174 std::vector<int32_t> get_task_vector_rhs() const 00175 { 00176 return task_vector_rhs; 00177 } 00178 00179 00181 void set_task_vector_rhs(std::vector<int32_t> vec) 00182 { 00183 00184 task_vector_rhs.clear(); 00185 00186 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00187 { 00188 task_vector_rhs.push_back(vec[i]); 00189 } 00190 00191 } 00192 00194 void set_task_vector(std::vector<int32_t> vec) 00195 { 00196 set_task_vector_lhs(vec); 00197 set_task_vector_rhs(vec); 00198 } 00199 00200 00206 float64_t get_similarity(int32_t task_lhs, int32_t task_rhs) 00207 { 00208 00209 const bool lhs_is_in = active_tasks.find(task_lhs) != active_tasks.end(); 00210 const bool rhs_is_in = active_tasks.find(task_rhs) != active_tasks.end(); 00211 00212 float64_t similarity = 0.0; 00213 00214 if (lhs_is_in && rhs_is_in) 00215 { 00216 similarity = 1.0 / normalization_constant; 00217 } 00218 00219 return similarity; 00220 00221 } 00222 00226 std::vector<int32_t> get_active_tasks() 00227 { 00228 00229 std::vector<int32_t> active_tasks_vec; 00230 00231 // set active tasks 00232 for (std::set<int32_t>::const_iterator it=active_tasks.begin(); it!=active_tasks.end(); it++) 00233 { 00234 active_tasks_vec.push_back(*it); 00235 } 00236 00237 return active_tasks_vec; 00238 } 00239 00243 float64_t get_normalization_constant () const 00244 { 00245 return normalization_constant; 00246 } 00247 00251 float64_t set_normalization_constant(float64_t constant) 00252 { 00253 normalization_constant = constant; 00254 00255 SG_NOTIMPLEMENTED; 00256 return 0.0; 00257 } 00258 00260 inline virtual const char* get_name() const 00261 { 00262 return "MultitaskKernelMaskNormalizer"; 00263 } 00264 00268 CMultitaskKernelMaskNormalizer* KernelNormalizerToMultitaskKernelMaskNormalizer(CKernelNormalizer* n) 00269 { 00270 return dynamic_cast<CMultitaskKernelMaskNormalizer*>(n); 00271 } 00272 00273 protected: 00275 std::set<int32_t> active_tasks; 00276 00278 std::vector<int32_t> task_vector_lhs; 00279 00281 std::vector<int32_t> task_vector_rhs; 00282 00284 float64_t scale; 00285 00287 float64_t normalization_constant; 00288 00289 }; 00290 } 00291 #endif