00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <shogun/features/FKFeatures.h>
00013 #include <shogun/features/StringFeatures.h>
00014 #include <shogun/io/SGIO.h>
00015 #include <shogun/base/Parameter.h>
00016
00017 using namespace shogun;
00018
00019 CFKFeatures::CFKFeatures() : CSimpleFeatures<float64_t>()
00020 {
00021 init();
00022 }
00023
00024 CFKFeatures::CFKFeatures(int32_t size, CHMM* p, CHMM* n)
00025 : CSimpleFeatures<float64_t>(size)
00026 {
00027 init();
00028 weight_a=-1;
00029 set_models(p,n);
00030 }
00031
00032 CFKFeatures::CFKFeatures(const CFKFeatures &orig)
00033 : CSimpleFeatures<float64_t>(orig), pos(orig.pos), neg(orig.neg), weight_a(orig.weight_a)
00034 {
00035 }
00036
00037 CFKFeatures::~CFKFeatures()
00038 {
00039 SG_UNREF(pos);
00040 SG_UNREF(neg);
00041 }
00042
00043 float64_t CFKFeatures::deriv_a(float64_t a, int32_t dimension)
00044 {
00045 CStringFeatures<uint16_t> *Obs=pos->get_observations() ;
00046 float64_t deriv=0.0 ;
00047 int32_t i=dimension ;
00048
00049 if (dimension==-1)
00050 {
00051 for (i=0; i<Obs->get_num_vectors(); i++)
00052 {
00053
00054
00055 float64_t pp=(pos_prob) ? pos_prob[i] : pos->model_probability(i);
00056 float64_t pn=(neg_prob) ? neg_prob[i] : neg->model_probability(i);
00057 float64_t sub=pp ;
00058 if (pn>pp) sub=pn ;
00059 pp-=sub ;
00060 pn-=sub ;
00061 pp=exp(pp) ;
00062 pn=exp(pn) ;
00063 float64_t p=a*pp+(1-a)*pn ;
00064 deriv+=(pp-pn)/p ;
00065
00066
00067
00068
00069
00070
00071
00072 } ;
00073 } else
00074 {
00075 float64_t pp=pos->model_probability(i) ;
00076 float64_t pn=neg->model_probability(i) ;
00077 float64_t sub=pp ;
00078 if (pn>pp) sub=pn ;
00079 pp-=sub ;
00080 pn-=sub ;
00081 pp=exp(pp) ;
00082 pn=exp(pn) ;
00083 float64_t p=a*pp+(1-a)*pn ;
00084 deriv+=(pp-pn)/p ;
00085 } ;
00086
00087 return deriv ;
00088 }
00089
00090
00091 float64_t CFKFeatures::set_opt_a(float64_t a)
00092 {
00093 if (a==-1)
00094 {
00095 SG_INFO( "estimating a.\n");
00096 pos_prob=SG_MALLOC(float64_t, pos->get_observations()->get_num_vectors());
00097 neg_prob=SG_MALLOC(float64_t, pos->get_observations()->get_num_vectors());
00098 for (int32_t i=0; i<pos->get_observations()->get_num_vectors(); i++)
00099 {
00100 pos_prob[i]=pos->model_probability(i) ;
00101 neg_prob[i]=neg->model_probability(i) ;
00102 }
00103
00104 float64_t la=0;
00105 float64_t ua=1;
00106 a=(la+ua)/2;
00107 while (CMath::abs(ua-la)>1e-6)
00108 {
00109 float64_t da=deriv_a(a);
00110 if (da>0)
00111 la=a;
00112 if (da<=0)
00113 ua=a;
00114 a=(la+ua)/2;
00115 SG_INFO( "opt_a: a=%1.3e deriv=%1.3e la=%1.3e ua=%1.3e\n", a, da, la ,ua);
00116 }
00117 SG_FREE(pos_prob);
00118 SG_FREE(neg_prob);
00119 pos_prob=NULL;
00120 neg_prob=NULL;
00121 }
00122
00123 weight_a=a;
00124 SG_INFO( "setting opt_a: %g\n", a);
00125 return a;
00126 }
00127
00128 void CFKFeatures::set_models(CHMM* p, CHMM* n)
00129 {
00130 ASSERT(p && n);
00131 SG_REF(p);
00132 SG_REF(n);
00133
00134 pos=p;
00135 neg=n;
00136 set_num_vectors(0);
00137
00138 free_feature_matrix();
00139
00140 SG_INFO( "pos_feat=[%i,%i,%i,%i],neg_feat=[%i,%i,%i,%i]\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()) ;
00141
00142 if (pos && pos->get_observations())
00143 set_num_vectors(pos->get_observations()->get_num_vectors());
00144 if (pos && neg)
00145 num_features=1+pos->get_N()*(1+pos->get_N()+1+pos->get_M()) + neg->get_N()*(1+neg->get_N()+1+neg->get_M()) ;
00146 }
00147
00148 float64_t* CFKFeatures::compute_feature_vector(
00149 int32_t num, int32_t &len, float64_t* target)
00150 {
00151 float64_t* featurevector=target;
00152
00153 if (!featurevector)
00154 featurevector=SG_MALLOC(float64_t,
00155 1+
00156 pos->get_N()*(1+pos->get_N()+1+pos->get_M())+
00157 neg->get_N()*(1+neg->get_N()+1+neg->get_M())
00158 );
00159
00160 if (!featurevector)
00161 return NULL;
00162
00163 compute_feature_vector(featurevector, num, len);
00164
00165 return featurevector;
00166 }
00167
00168 void CFKFeatures::compute_feature_vector(
00169 float64_t* featurevector, int32_t num, int32_t& len)
00170 {
00171 int32_t i,j,p=0,x=num;
00172
00173 float64_t posx=pos->model_probability(x);
00174 float64_t negx=neg->model_probability(x);
00175
00176 len=1+pos->get_N()*(1+pos->get_N()+1+pos->get_M()) + neg->get_N()*(1+neg->get_N()+1+neg->get_M());
00177
00178 featurevector[p++] = deriv_a(weight_a, x);
00179 float64_t px=CMath::logarithmic_sum(
00180 posx+log(weight_a),negx+log(1-weight_a));
00181
00182
00183 for (i=0; i<pos->get_N(); i++)
00184 {
00185 featurevector[p++]=weight_a*exp(pos->model_derivative_p(i, x)-px);
00186 featurevector[p++]=weight_a*exp(pos->model_derivative_q(i, x)-px);
00187
00188 for (j=0; j<pos->get_N(); j++) {
00189 featurevector[p++]=weight_a*exp(pos->model_derivative_a(i, j, x)-px);
00190 }
00191
00192 for (j=0; j<pos->get_M(); j++) {
00193 featurevector[p++]=weight_a*exp(pos->model_derivative_b(i, j, x)-px);
00194 }
00195
00196 }
00197
00198
00199 for (i=0; i<neg->get_N(); i++)
00200 {
00201 featurevector[p++]= (1-weight_a)*exp(neg->model_derivative_p(i, x)-px);
00202 featurevector[p++]= (1-weight_a)* exp(neg->model_derivative_q(i, x)-px);
00203
00204 for (j=0; j<neg->get_N(); j++) {
00205 featurevector[p++]= (1-weight_a)*exp(neg->model_derivative_a(i, j, x)-px);
00206 }
00207
00208 for (j=0; j<neg->get_M(); j++) {
00209 featurevector[p++]= (1-weight_a)*exp(neg->model_derivative_b(i, j, x)-px);
00210 }
00211 }
00212 }
00213
00214 float64_t* CFKFeatures::set_feature_matrix()
00215 {
00216 ASSERT(pos);
00217 ASSERT(pos->get_observations());
00218 ASSERT(neg);
00219 ASSERT(neg->get_observations());
00220
00221 int32_t len=0;
00222 num_features=1+ pos->get_N()*(1+pos->get_N()+1+pos->get_M()) + neg->get_N()*(1+neg->get_N()+1+neg->get_M());
00223
00224 num_vectors=pos->get_observations()->get_num_vectors();
00225 ASSERT(num_vectors);
00226
00227 SG_INFO( "allocating FK feature cache of size %.2fM\n", sizeof(float64_t)*num_features*num_vectors/1024.0/1024.0);
00228 free_feature_matrix();
00229 feature_matrix=SG_MALLOC(float64_t, num_features*num_vectors);
00230
00231 SG_INFO( "calculating FK feature matrix\n");
00232
00233 for (int32_t x=0; x<num_vectors; x++)
00234 {
00235 if (!(x % (num_vectors/10+1)))
00236 SG_DEBUG("%02d%%.", (int) (100.0*x/num_vectors));
00237 else if (!(x % (num_vectors/200+1)))
00238 SG_DEBUG(".");
00239
00240 compute_feature_vector(&feature_matrix[x*num_features], x, len);
00241 }
00242
00243 SG_DONE();
00244
00245 num_vectors=get_num_vectors();
00246 num_features=get_num_features();
00247
00248 return feature_matrix;
00249 }
00250
00251 void CFKFeatures::init()
00252 {
00253 pos = NULL;
00254 neg = NULL;
00255 pos_prob = NULL;
00256 neg_prob = NULL;
00257 weight_a = 0.0;
00258
00259 unset_generic();
00260
00261
00262
00263 m_parameters->add(&weight_a, "weight_a", "Class prior.");
00264 }