TOPFeatures.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation