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 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2009 Soeren Sonnenburg 00008 * Written (W) 1999-2008 Gunnar Raetsch 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #include <shogun/features/TOPFeatures.h> 00013 #include <shogun/io/SGIO.h> 00014 #include <shogun/mathematics/Math.h> 00015 00016 using namespace shogun; 00017 00018 CTOPFeatures::CTOPFeatures() 00019 { 00020 init(); 00021 } 00022 00023 CTOPFeatures::CTOPFeatures( 00024 int32_t size, CHMM* p, CHMM* n, bool neglin, bool poslin) 00025 : CDenseFeatures<float64_t>(size) 00026 { 00027 init(); 00028 neglinear=neglin; 00029 poslinear=poslin; 00030 00031 set_models(p,n); 00032 } 00033 00034 CTOPFeatures::CTOPFeatures(const CTOPFeatures &orig) 00035 : CDenseFeatures<float64_t>(orig) 00036 { 00037 init(); 00038 pos=orig.pos; 00039 neg=orig.neg; 00040 neglinear=orig.neglinear; 00041 poslinear=orig.poslinear; 00042 } 00043 00044 CTOPFeatures::~CTOPFeatures() 00045 { 00046 SG_FREE(pos_relevant_indizes.idx_p); 00047 SG_FREE(pos_relevant_indizes.idx_q); 00048 SG_FREE(pos_relevant_indizes.idx_a_cols); 00049 SG_FREE(pos_relevant_indizes.idx_a_rows); 00050 SG_FREE(pos_relevant_indizes.idx_b_cols); 00051 SG_FREE(pos_relevant_indizes.idx_b_rows); 00052 00053 SG_FREE(neg_relevant_indizes.idx_p); 00054 SG_FREE(neg_relevant_indizes.idx_q); 00055 SG_FREE(neg_relevant_indizes.idx_a_cols); 00056 SG_FREE(neg_relevant_indizes.idx_a_rows); 00057 SG_FREE(neg_relevant_indizes.idx_b_cols); 00058 SG_FREE(neg_relevant_indizes.idx_b_rows); 00059 00060 SG_UNREF(pos); 00061 SG_UNREF(neg); 00062 } 00063 00064 void CTOPFeatures::set_models(CHMM* p, CHMM* n) 00065 { 00066 ASSERT(p && n); 00067 SG_REF(p); 00068 SG_REF(n); 00069 00070 pos=p; 00071 neg=n; 00072 set_num_vectors(0); 00073 00074 feature_matrix=SGMatrix<float64_t>(); 00075 00076 if (pos && pos->get_observations()) 00077 set_num_vectors(pos->get_observations()->get_num_vectors()); 00078 00079 compute_relevant_indizes(p, &pos_relevant_indizes); 00080 compute_relevant_indizes(n, &neg_relevant_indizes); 00081 num_features=compute_num_features(); 00082 00083 SG_DEBUG( "pos_feat=[%i,%i,%i,%i],neg_feat=[%i,%i,%i,%i] -> %i features\n", pos->get_N(), pos->get_N(), pos->get_N()*pos->get_N(), pos->get_N()*pos->get_M(), neg->get_N(), neg->get_N(), neg->get_N()*neg->get_N(), neg->get_N()*neg->get_M(),num_features) ; 00084 } 00085 00086 float64_t* CTOPFeatures::compute_feature_vector( 00087 int32_t num, int32_t &len, float64_t* target) 00088 { 00089 float64_t* featurevector=target; 00090 00091 if (!featurevector) 00092 featurevector=SG_MALLOC(float64_t, get_num_features()); 00093 00094 if (!featurevector) 00095 return NULL; 00096 00097 compute_feature_vector(featurevector, num, len); 00098 00099 return featurevector; 00100 } 00101 00102 void CTOPFeatures::compute_feature_vector( 00103 float64_t* featurevector, int32_t num, int32_t& len) 00104 { 00105 int32_t i,j,p=0,x=num; 00106 int32_t idx=0; 00107 00108 float64_t posx=(poslinear) ? 00109 (pos->linear_model_probability(x)) : (pos->model_probability(x)); 00110 float64_t negx=(neglinear) ? 00111 (neg->linear_model_probability(x)) : (neg->model_probability(x)); 00112 00113 len=get_num_features(); 00114 00115 featurevector[p++]=(posx-negx); 00116 00117 //first do positive model 00118 if (poslinear) 00119 { 00120 for (i=0; i<pos->get_N(); i++) 00121 { 00122 for (j=0; j<pos->get_M(); j++) 00123 featurevector[p++]=exp(pos->linear_model_derivative(i, j, x)-posx); 00124 } 00125 } 00126 else 00127 { 00128 for (idx=0; idx< pos_relevant_indizes.num_p; idx++) 00129 featurevector[p++]=exp(pos->model_derivative_p(pos_relevant_indizes.idx_p[idx], x)-posx); 00130 00131 for (idx=0; idx< pos_relevant_indizes.num_q; idx++) 00132 featurevector[p++]=exp(pos->model_derivative_q(pos_relevant_indizes.idx_q[idx], x)-posx); 00133 00134 for (idx=0; idx< pos_relevant_indizes.num_a; idx++) 00135 featurevector[p++]=exp(pos->model_derivative_a(pos_relevant_indizes.idx_a_rows[idx], pos_relevant_indizes.idx_a_cols[idx], x)-posx); 00136 00137 for (idx=0; idx< pos_relevant_indizes.num_b; idx++) 00138 featurevector[p++]=exp(pos->model_derivative_b(pos_relevant_indizes.idx_b_rows[idx], pos_relevant_indizes.idx_b_cols[idx], x)-posx); 00139 00140 00141 //for (i=0; i<pos->get_N(); i++) 00142 //{ 00143 // featurevector[p++]=exp(pos->model_derivative_p(i, x)-posx); 00144 // featurevector[p++]=exp(pos->model_derivative_q(i, x)-posx); 00145 00146 // for (j=0; j<pos->get_N(); j++) 00147 // featurevector[p++]=exp(pos->model_derivative_a(i, j, x)-posx); 00148 00149 // for (j=0; j<pos->get_M(); j++) 00150 // featurevector[p++]=exp(pos->model_derivative_b(i, j, x)-posx); 00151 //} 00152 } 00153 00154 //then do negative 00155 if (neglinear) 00156 { 00157 for (i=0; i<neg->get_N(); i++) 00158 { 00159 for (j=0; j<neg->get_M(); j++) 00160 featurevector[p++]= - exp(neg->linear_model_derivative(i, j, x)-negx); 00161 } 00162 } 00163 else 00164 { 00165 for (idx=0; idx< neg_relevant_indizes.num_p; idx++) 00166 featurevector[p++]= - exp(neg->model_derivative_p(neg_relevant_indizes.idx_p[idx], x)-negx); 00167 00168 for (idx=0; idx< neg_relevant_indizes.num_q; idx++) 00169 featurevector[p++]= - exp(neg->model_derivative_q(neg_relevant_indizes.idx_q[idx], x)-negx); 00170 00171 for (idx=0; idx< neg_relevant_indizes.num_a; idx++) 00172 featurevector[p++]= - exp(neg->model_derivative_a(neg_relevant_indizes.idx_a_rows[idx], neg_relevant_indizes.idx_a_cols[idx], x)-negx); 00173 00174 for (idx=0; idx< neg_relevant_indizes.num_b; idx++) 00175 featurevector[p++]= - exp(neg->model_derivative_b(neg_relevant_indizes.idx_b_rows[idx], neg_relevant_indizes.idx_b_cols[idx], x)-negx); 00176 00177 //for (i=0; i<neg->get_N(); i++) 00178 //{ 00179 // featurevector[p++]= - exp(neg->model_derivative_p(i, x)-negx); 00180 // featurevector[p++]= - exp(neg->model_derivative_q(i, x)-negx); 00181 00182 // for (j=0; j<neg->get_N(); j++) 00183 // featurevector[p++]= - exp(neg->model_derivative_a(i, j, x)-negx); 00184 00185 // for (j=0; j<neg->get_M(); j++) 00186 // featurevector[p++]= - exp(neg->model_derivative_b(i, j, x)-negx); 00187 //} 00188 } 00189 } 00190 00191 float64_t* CTOPFeatures::set_feature_matrix() 00192 { 00193 int32_t len=0; 00194 00195 num_features=get_num_features(); 00196 ASSERT(num_features); 00197 ASSERT(pos); 00198 ASSERT(pos->get_observations()); 00199 00200 num_vectors=pos->get_observations()->get_num_vectors(); 00201 SG_INFO( "allocating top feature cache of size %.2fM\n", sizeof(float64_t)*num_features*num_vectors/1024.0/1024.0); 00202 feature_matrix = SGMatrix<float64_t>(num_features,num_vectors); 00203 if (!feature_matrix.matrix) 00204 { 00205 SG_ERROR( "allocation not successful!"); 00206 return NULL ; 00207 } ; 00208 00209 SG_INFO( "calculating top feature matrix\n"); 00210 00211 for (int32_t x=0; x<num_vectors; x++) 00212 { 00213 if (!(x % (num_vectors/10+1))) 00214 SG_DEBUG( "%02d%%.", (int) (100.0*x/num_vectors)); 00215 else if (!(x % (num_vectors/200+1))) 00216 SG_DEBUG( "."); 00217 00218 compute_feature_vector(&feature_matrix[x*num_features], x, len); 00219 } 00220 00221 SG_DONE(); 00222 00223 num_vectors=get_num_vectors() ; 00224 num_features=get_num_features() ; 00225 00226 return feature_matrix.matrix; 00227 } 00228 00229 bool CTOPFeatures::compute_relevant_indizes(CHMM* hmm, T_HMM_INDIZES* hmm_idx) 00230 { 00231 int32_t i=0; 00232 int32_t j=0; 00233 00234 hmm_idx->num_p=0; 00235 hmm_idx->num_q=0; 00236 hmm_idx->num_a=0; 00237 hmm_idx->num_b=0; 00238 00239 for (i=0; i<hmm->get_N(); i++) 00240 { 00241 if (hmm->get_p(i)>CMath::ALMOST_NEG_INFTY) 00242 hmm_idx->num_p++; 00243 00244 if (hmm->get_q(i)>CMath::ALMOST_NEG_INFTY) 00245 hmm_idx->num_q++; 00246 00247 for (j=0; j<hmm->get_N(); j++) 00248 { 00249 if (hmm->get_a(i,j)>CMath::ALMOST_NEG_INFTY) 00250 hmm_idx->num_a++; 00251 } 00252 00253 for (j=0; j<pos->get_M(); j++) 00254 { 00255 if (hmm->get_b(i,j)>CMath::ALMOST_NEG_INFTY) 00256 hmm_idx->num_b++; 00257 } 00258 } 00259 00260 if (hmm_idx->num_p > 0) 00261 { 00262 hmm_idx->idx_p=SG_MALLOC(int32_t, hmm_idx->num_p); 00263 ASSERT(hmm_idx->idx_p); 00264 } 00265 00266 if (hmm_idx->num_q > 0) 00267 { 00268 hmm_idx->idx_q=SG_MALLOC(int32_t, hmm_idx->num_q); 00269 ASSERT(hmm_idx->idx_q); 00270 } 00271 00272 if (hmm_idx->num_a > 0) 00273 { 00274 hmm_idx->idx_a_rows=SG_MALLOC(int32_t, hmm_idx->num_a); 00275 hmm_idx->idx_a_cols=SG_MALLOC(int32_t, hmm_idx->num_a); 00276 ASSERT(hmm_idx->idx_a_rows); 00277 ASSERT(hmm_idx->idx_a_cols); 00278 } 00279 00280 if (hmm_idx->num_b > 0) 00281 { 00282 hmm_idx->idx_b_rows=SG_MALLOC(int32_t, hmm_idx->num_b); 00283 hmm_idx->idx_b_cols=SG_MALLOC(int32_t, hmm_idx->num_b); 00284 ASSERT(hmm_idx->idx_b_rows); 00285 ASSERT(hmm_idx->idx_b_cols); 00286 } 00287 00288 00289 int32_t idx_p=0; 00290 int32_t idx_q=0; 00291 int32_t idx_a=0; 00292 int32_t idx_b=0; 00293 00294 for (i=0; i<hmm->get_N(); i++) 00295 { 00296 if (hmm->get_p(i)>CMath::ALMOST_NEG_INFTY) 00297 { 00298 ASSERT(idx_p < hmm_idx->num_p); 00299 hmm_idx->idx_p[idx_p++]=i; 00300 } 00301 00302 if (hmm->get_q(i)>CMath::ALMOST_NEG_INFTY) 00303 { 00304 ASSERT(idx_q < hmm_idx->num_q); 00305 hmm_idx->idx_q[idx_q++]=i; 00306 } 00307 00308 for (j=0; j<hmm->get_N(); j++) 00309 { 00310 if (hmm->get_a(i,j)>CMath::ALMOST_NEG_INFTY) 00311 { 00312 ASSERT(idx_a < hmm_idx->num_a); 00313 hmm_idx->idx_a_rows[idx_a]=i; 00314 hmm_idx->idx_a_cols[idx_a++]=j; 00315 } 00316 } 00317 00318 for (j=0; j<pos->get_M(); j++) 00319 { 00320 if (hmm->get_b(i,j)>CMath::ALMOST_NEG_INFTY) 00321 { 00322 ASSERT(idx_b < hmm_idx->num_b); 00323 hmm_idx->idx_b_rows[idx_b]=i; 00324 hmm_idx->idx_b_cols[idx_b++]=j; 00325 } 00326 } 00327 } 00328 00329 return true; 00330 } 00331 00332 int32_t CTOPFeatures::compute_num_features() 00333 { 00334 int32_t num=0; 00335 00336 if (pos && neg) 00337 { 00338 num+=1; //zeroth- component 00339 00340 if (poslinear) 00341 num+=pos->get_N()*pos->get_M(); 00342 else 00343 { 00344 num+= pos_relevant_indizes.num_p + pos_relevant_indizes.num_q + pos_relevant_indizes.num_a + pos_relevant_indizes.num_b; 00345 } 00346 00347 if (neglinear) 00348 num+=neg->get_N()*neg->get_M(); 00349 else 00350 { 00351 num+= neg_relevant_indizes.num_p + neg_relevant_indizes.num_q + neg_relevant_indizes.num_a + neg_relevant_indizes.num_b; 00352 } 00353 00354 //num+=1; //zeroth- component 00355 //num+= (poslinear) ? (pos->get_N()*pos->get_M()) : (pos->get_N()*(1+pos->get_N()+1+pos->get_M())); 00356 //num+= (neglinear) ? (neg->get_N()*neg->get_M()) : (neg->get_N()*(1+neg->get_N()+1+neg->get_M())); 00357 } 00358 return num; 00359 } 00360 00361 void CTOPFeatures::init() 00362 { 00363 pos = NULL; 00364 neg = NULL; 00365 neglinear = false; 00366 poslinear = false; 00367 00368 memset(&pos_relevant_indizes, 0, sizeof(pos_relevant_indizes)); 00369 memset(&neg_relevant_indizes, 0, sizeof(neg_relevant_indizes)); 00370 00371 unset_generic(); 00372 //TODO serialize HMMs 00373 //m_parameters->add((CSGObject**) &pos, "pos", "HMM for positive class."); 00374 //m_parameters->add((CSGObject**) &neg, "neg", "HMM for negative class."); 00375 m_parameters->add(&neglinear, "neglinear", "If negative HMM is a LinearHMM"); 00376 m_parameters->add(&poslinear, "poslinear", "If positive HMM is a LinearHMM"); 00377 }