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 _MULTITASKKERNELMASKPAIRNORMALIZER_H___ 00012 #define _MULTITASKKERNELMASKPAIRNORMALIZER_H___ 00013 00014 #include <shogun/kernel/normalizer/KernelNormalizer.h> 00015 #include <shogun/kernel/Kernel.h> 00016 00017 #include <string> 00018 #include <vector> 00019 #include <utility> 00020 00021 namespace shogun 00022 { 00023 00024 00029 class CMultitaskKernelMaskPairNormalizer: public CKernelNormalizer 00030 { 00031 00032 public: 00033 00036 CMultitaskKernelMaskPairNormalizer() : 00037 CKernelNormalizer(), scale(1.0), normalization_constant(1.0) 00038 { 00039 } 00040 00045 CMultitaskKernelMaskPairNormalizer(std::vector<int32_t> task_vector_, 00046 std::vector<std::pair<int32_t, int32_t> > active_pairs_) : 00047 scale(1.0), normalization_constant(1.0) 00048 { 00049 00050 set_task_vector(task_vector_); 00051 active_pairs = active_pairs_; 00052 00053 } 00054 00055 00057 virtual ~CMultitaskKernelMaskPairNormalizer() 00058 { 00059 } 00060 00063 virtual bool init(CKernel* k) 00064 { 00065 ASSERT(k) 00066 int32_t num_lhs = k->get_num_vec_lhs(); 00067 int32_t num_rhs = k->get_num_vec_rhs(); 00068 ASSERT(num_lhs>0) 00069 ASSERT(num_rhs>0) 00070 00071 00072 //same as first-element normalizer 00073 CFeatures* old_lhs=k->lhs; 00074 CFeatures* old_rhs=k->rhs; 00075 k->lhs=old_lhs; 00076 k->rhs=old_lhs; 00077 00078 00079 if (std::string(k->get_name()) == "WeightedDegree") { 00080 SG_INFO("using first-element normalization\n") 00081 scale=k->compute(0, 0); 00082 } else { 00083 SG_INFO("no inner normalization for non-WDK kernel\n") 00084 scale=1.0; 00085 } 00086 00087 k->lhs=old_lhs; 00088 k->rhs=old_rhs; 00089 00090 00091 return true; 00092 } 00093 00094 00095 00101 virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00102 { 00103 00104 //lookup tasks 00105 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00106 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00107 00108 //lookup similarity 00109 float64_t task_similarity = get_similarity(task_idx_lhs, task_idx_rhs); 00110 00111 //take task similarity into account 00112 float64_t similarity = (value/scale) * task_similarity; 00113 00114 00115 return similarity; 00116 00117 } 00118 00123 virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00124 { 00125 SG_ERROR("normalize_lhs not implemented") 00126 return 0; 00127 } 00128 00133 virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00134 { 00135 SG_ERROR("normalize_rhs not implemented") 00136 return 0; 00137 } 00138 00140 std::vector<int32_t> get_task_vector_lhs() const 00141 { 00142 return task_vector_lhs; 00143 } 00144 00145 00147 void set_task_vector_lhs(std::vector<int32_t> vec) 00148 { 00149 00150 task_vector_lhs.clear(); 00151 00152 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00153 { 00154 task_vector_lhs.push_back(vec[i]); 00155 } 00156 00157 } 00158 00161 std::vector<int32_t> get_task_vector_rhs() const 00162 { 00163 return task_vector_rhs; 00164 } 00165 00166 00168 void set_task_vector_rhs(std::vector<int32_t> vec) 00169 { 00170 00171 task_vector_rhs.clear(); 00172 00173 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00174 { 00175 task_vector_rhs.push_back(vec[i]); 00176 } 00177 00178 } 00179 00181 void set_task_vector(std::vector<int32_t> vec) 00182 { 00183 set_task_vector_lhs(vec); 00184 set_task_vector_rhs(vec); 00185 } 00186 00187 00193 float64_t get_similarity(int32_t task_lhs, int32_t task_rhs) 00194 { 00195 00196 float64_t similarity = 0.0; 00197 00198 for (int32_t i=0; i!=static_cast<int>(active_pairs.size()); i++) 00199 { 00200 std::pair<int32_t, int32_t> block = active_pairs[i]; 00201 00202 // ignore order of pair 00203 if ((block.first==task_lhs && block.second==task_rhs) || 00204 (block.first==task_rhs && block.second==task_lhs)) 00205 { 00206 similarity = 1.0 / normalization_constant; 00207 break; 00208 } 00209 } 00210 00211 00212 return similarity; 00213 00214 } 00215 00217 std::vector<std::pair<int32_t, int32_t> > get_active_pairs() 00218 { 00219 return active_pairs; 00220 } 00221 00223 float64_t get_normalization_constant () const 00224 { 00225 return normalization_constant; 00226 } 00227 00229 float64_t set_normalization_constant(float64_t constant) 00230 { 00231 normalization_constant = constant; 00232 00233 SG_NOTIMPLEMENTED 00234 return 0.0; 00235 } 00236 00237 00239 virtual const char* get_name() const 00240 { 00241 return "MultitaskKernelMaskPairNormalizer"; 00242 } 00243 00247 CMultitaskKernelMaskPairNormalizer* KernelNormalizerToMultitaskKernelMaskPairNormalizer(CKernelNormalizer* n) 00248 { 00249 return dynamic_cast<shogun::CMultitaskKernelMaskPairNormalizer*>(n); 00250 } 00251 00252 protected: 00253 00255 std::vector<std::pair<int32_t, int32_t> > active_pairs; 00256 00258 std::vector<int32_t> task_vector_lhs; 00259 00261 std::vector<int32_t> task_vector_rhs; 00262 00264 float64_t scale; 00265 00267 float64_t normalization_constant; 00268 00269 }; 00270 } 00271 #endif