SHOGUN
v2.0.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 00019 namespace shogun 00020 { 00021 00022 00027 class CMultitaskKernelMaskPairNormalizer: public CKernelNormalizer 00028 { 00029 00030 public: 00031 00034 CMultitaskKernelMaskPairNormalizer() : 00035 CKernelNormalizer(), scale(1.0), normalization_constant(1.0) 00036 { 00037 } 00038 00043 CMultitaskKernelMaskPairNormalizer(std::vector<int32_t> task_vector_, 00044 std::vector<std::pair<int32_t, int32_t> > active_pairs_) : 00045 scale(1.0), normalization_constant(1.0) 00046 { 00047 00048 set_task_vector(task_vector_); 00049 active_pairs = active_pairs_; 00050 00051 } 00052 00053 00055 virtual ~CMultitaskKernelMaskPairNormalizer() 00056 { 00057 } 00058 00061 virtual bool init(CKernel* k) 00062 { 00063 ASSERT(k); 00064 int32_t num_lhs = k->get_num_vec_lhs(); 00065 int32_t num_rhs = k->get_num_vec_rhs(); 00066 ASSERT(num_lhs>0); 00067 ASSERT(num_rhs>0); 00068 00069 00070 //same as first-element normalizer 00071 CFeatures* old_lhs=k->lhs; 00072 CFeatures* old_rhs=k->rhs; 00073 k->lhs=old_lhs; 00074 k->rhs=old_lhs; 00075 00076 00077 if (std::string(k->get_name()) == "WeightedDegree") { 00078 SG_INFO("using first-element normalization\n"); 00079 scale=k->compute(0, 0); 00080 } else { 00081 SG_INFO("no inner normalization for non-WDK kernel\n"); 00082 scale=1.0; 00083 } 00084 00085 k->lhs=old_lhs; 00086 k->rhs=old_rhs; 00087 00088 00089 return true; 00090 } 00091 00092 00093 00099 inline virtual float64_t normalize(float64_t value, int32_t idx_lhs, int32_t idx_rhs) 00100 { 00101 00102 //lookup tasks 00103 int32_t task_idx_lhs = task_vector_lhs[idx_lhs]; 00104 int32_t task_idx_rhs = task_vector_rhs[idx_rhs]; 00105 00106 //lookup similarity 00107 float64_t task_similarity = get_similarity(task_idx_lhs, task_idx_rhs); 00108 00109 //take task similarity into account 00110 float64_t similarity = (value/scale) * task_similarity; 00111 00112 00113 return similarity; 00114 00115 } 00116 00121 inline virtual float64_t normalize_lhs(float64_t value, int32_t idx_lhs) 00122 { 00123 SG_ERROR("normalize_lhs not implemented"); 00124 return 0; 00125 } 00126 00131 inline virtual float64_t normalize_rhs(float64_t value, int32_t idx_rhs) 00132 { 00133 SG_ERROR("normalize_rhs not implemented"); 00134 return 0; 00135 } 00136 00138 std::vector<int32_t> get_task_vector_lhs() const 00139 { 00140 return task_vector_lhs; 00141 } 00142 00143 00145 void set_task_vector_lhs(std::vector<int32_t> vec) 00146 { 00147 00148 task_vector_lhs.clear(); 00149 00150 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00151 { 00152 task_vector_lhs.push_back(vec[i]); 00153 } 00154 00155 } 00156 00159 std::vector<int32_t> get_task_vector_rhs() const 00160 { 00161 return task_vector_rhs; 00162 } 00163 00164 00166 void set_task_vector_rhs(std::vector<int32_t> vec) 00167 { 00168 00169 task_vector_rhs.clear(); 00170 00171 for (int32_t i = 0; i != (int32_t)(vec.size()); ++i) 00172 { 00173 task_vector_rhs.push_back(vec[i]); 00174 } 00175 00176 } 00177 00179 void set_task_vector(std::vector<int32_t> vec) 00180 { 00181 set_task_vector_lhs(vec); 00182 set_task_vector_rhs(vec); 00183 } 00184 00185 00191 float64_t get_similarity(int32_t task_lhs, int32_t task_rhs) 00192 { 00193 00194 float64_t similarity = 0.0; 00195 00196 for (int32_t i=0; i!=static_cast<int>(active_pairs.size()); i++) 00197 { 00198 std::pair<int32_t, int32_t> block = active_pairs[i]; 00199 00200 // ignore order of pair 00201 if ((block.first==task_lhs && block.second==task_rhs) || 00202 (block.first==task_rhs && block.second==task_lhs)) 00203 { 00204 similarity = 1.0 / normalization_constant; 00205 break; 00206 } 00207 } 00208 00209 00210 return similarity; 00211 00212 } 00213 00215 std::vector<std::pair<int32_t, int32_t> > get_active_pairs() 00216 { 00217 return active_pairs; 00218 } 00219 00221 float64_t get_normalization_constant () const 00222 { 00223 return normalization_constant; 00224 } 00225 00227 float64_t set_normalization_constant(float64_t constant) 00228 { 00229 normalization_constant = constant; 00230 00231 SG_NOTIMPLEMENTED; 00232 return 0.0; 00233 } 00234 00235 00237 inline virtual const char* get_name() const 00238 { 00239 return "MultitaskKernelMaskPairNormalizer"; 00240 } 00241 00245 CMultitaskKernelMaskPairNormalizer* KernelNormalizerToMultitaskKernelMaskPairNormalizer(CKernelNormalizer* n) 00246 { 00247 return dynamic_cast<shogun::CMultitaskKernelMaskPairNormalizer*>(n); 00248 } 00249 00250 protected: 00251 00253 std::vector<std::pair<int32_t, int32_t> > active_pairs; 00254 00256 std::vector<int32_t> task_vector_lhs; 00257 00259 std::vector<int32_t> task_vector_rhs; 00260 00262 float64_t scale; 00263 00265 float64_t normalization_constant; 00266 00267 }; 00268 } 00269 #endif