SHOGUN
v3.2.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/normalizer/KernelNormalizer.h> 00015 #include <shogun/kernel/Kernel.h> 00016 #include <set> 00017 #include <string> 00018 #include <vector> 00019 00020 namespace shogun 00021 { 00022 00023 00034 class CMultitaskKernelMaskNormalizer: public CKernelNormalizer 00035 { 00036 00037 public: 00038 00041 CMultitaskKernelMaskNormalizer() : CKernelNormalizer(), 00042 scale(1.0), normalization_constant(1.0) 00043 { 00044 } 00045 00052 CMultitaskKernelMaskNormalizer(std::vector<int32_t> task_lhs, 00053 std::vector<int32_t> task_rhs, 00054 std::vector<int32_t> active_tasks_vec) 00055 : CKernelNormalizer(), scale(1.0), normalization_constant(1.0) 00056 { 00057 00058 00059 set_task_vector_lhs(task_lhs); 00060 set_task_vector_rhs(task_rhs); 00061 00062 // set active tasks 00063 for (int32_t i = 0; i != (int32_t)(active_tasks_vec.size()); ++i) 00064 { 00065 active_tasks.insert(active_tasks_vec[i]); 00066 } 00067 00068 } 00069 00070 00072 virtual ~CMultitaskKernelMaskNormalizer() 00073 { 00074 } 00075 00078 virtual bool init(CKernel* k) 00079 { 00080 ASSERT(k) 00081 int32_t num_lhs = k->get_num_vec_lhs(); 00082 int32_t num_rhs = k->get_num_vec_rhs(); 00083 ASSERT(num_lhs>0) 00084 ASSERT(num_rhs>0) 00085 00086 00087 //same as first-element normalizer 00088 CFeatures* old_lhs=k->lhs; 00089 CFeatures* old_rhs=k->rhs; 00090 k->lhs=old_lhs; 00091 k->rhs=old_lhs; 00092 00093 if (std::string(k->get_name()) == "WeightedDegree") { 00094 SG_INFO("using first-element normalization\n") 00095 scale=k->compute(0, 0); 00096 } else { 00097 SG_INFO("no inner normalization for non-WDK kernel\n") 00098 scale=1.0; 00099 } 00100 00101 k->lhs=old_lhs; 00102 k->rhs=old_rhs; 00103 00104 00105 return true; 00106 } 00107 00108 00109 00115 virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00116 { 00117 00118 //lookup tasks 00119 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00120 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00121 00122 //lookup similarity 00123 float64_t task_similarity = get_similarity(task_idx_lhs, task_idx_rhs); 00124 00125 //take task similarity into account 00126 float64_t similarity = (value/scale) * task_similarity; 00127 00128 00129 return similarity; 00130 00131 } 00132 00137 virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00138 { 00139 SG_ERROR("normalize_lhs not implemented") 00140 return 0; 00141 } 00142 00147 virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00148 { 00149 SG_ERROR("normalize_rhs not implemented") 00150 return 0; 00151 } 00152 00154 std::vector<int32_t> get_task_vector_lhs() const 00155 { 00156 return task_vector_lhs; 00157 } 00158 00159 00161 void set_task_vector_lhs(std::vector<int32_t> vec) 00162 { 00163 00164 task_vector_lhs.clear(); 00165 00166 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00167 { 00168 task_vector_lhs.push_back(vec[i]); 00169 } 00170 00171 } 00172 00175 std::vector<int32_t> get_task_vector_rhs() const 00176 { 00177 return task_vector_rhs; 00178 } 00179 00180 00182 void set_task_vector_rhs(std::vector<int32_t> vec) 00183 { 00184 00185 task_vector_rhs.clear(); 00186 00187 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00188 { 00189 task_vector_rhs.push_back(vec[i]); 00190 } 00191 00192 } 00193 00195 void set_task_vector(std::vector<int32_t> vec) 00196 { 00197 set_task_vector_lhs(vec); 00198 set_task_vector_rhs(vec); 00199 } 00200 00201 00207 float64_t get_similarity(int32_t task_lhs, int32_t task_rhs) 00208 { 00209 00210 const bool lhs_is_in = active_tasks.find(task_lhs) != active_tasks.end(); 00211 const bool rhs_is_in = active_tasks.find(task_rhs) != active_tasks.end(); 00212 00213 float64_t similarity = 0.0; 00214 00215 if (lhs_is_in && rhs_is_in) 00216 { 00217 similarity = 1.0 / normalization_constant; 00218 } 00219 00220 return similarity; 00221 00222 } 00223 00227 std::vector<int32_t> get_active_tasks() 00228 { 00229 00230 std::vector<int32_t> active_tasks_vec; 00231 00232 // set active tasks 00233 for (std::set<int32_t>::const_iterator it=active_tasks.begin(); it!=active_tasks.end(); it++) 00234 { 00235 active_tasks_vec.push_back(*it); 00236 } 00237 00238 return active_tasks_vec; 00239 } 00240 00244 float64_t get_normalization_constant () const 00245 { 00246 return normalization_constant; 00247 } 00248 00252 float64_t set_normalization_constant(float64_t constant) 00253 { 00254 normalization_constant = constant; 00255 00256 SG_NOTIMPLEMENTED 00257 return 0.0; 00258 } 00259 00261 virtual const char* get_name() const 00262 { 00263 return "MultitaskKernelMaskNormalizer"; 00264 } 00265 00269 CMultitaskKernelMaskNormalizer* KernelNormalizerToMultitaskKernelMaskNormalizer(CKernelNormalizer* n) 00270 { 00271 return dynamic_cast<CMultitaskKernelMaskNormalizer*>(n); 00272 } 00273 00274 protected: 00276 std::set<int32_t> active_tasks; 00277 00279 std::vector<int32_t> task_vector_lhs; 00280 00282 std::vector<int32_t> task_vector_rhs; 00283 00285 float64_t scale; 00286 00288 float64_t normalization_constant; 00289 00290 }; 00291 } 00292 #endif