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