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