objet code for the Optimzer algorithm

git-svn-id: https://mosesdecoder.svn.sourceforge.net/svnroot/mosesdecoder/trunk@1637 1f5c12ca-751b-0410-a591-d2e778427230
This commit is contained in:
jfouet 2008-05-14 11:00:59 +00:00
parent eb2d6e971d
commit f9448b76a0
2 changed files with 170 additions and 0 deletions

115
mert/Optimizer.cpp Normal file
View File

@ -0,0 +1,115 @@
#include <cassert>
#include "Optimizer.h"
#include <vector>
#include <cfloat>
#include <iostream>
using namespace std;
void Optimizer::SetScorer(Scorer *S){
if(scorer)
delete scorer;
scorer=S;
}
void Optimizer::SetFData(FeatureData *F){
if(FData)
delete FData;
FData=F;
};
float intersect (float b1,m1,b2,m2){
if(m1==m2)
return numeric_limit<float>::max();
return((b2-b1)/(m2-m1));
}
statscore Optimizer::LineOptimize(const point& start,point direction,point& best){
direction.normalize();//we pass by value so changing is ok
// we are looking for the best point on the line y=start+x*direction
vector< vector<float,unsigned> > onebest;
float min_int=0.00001;
multimap<float,unsigned> thresholdlist;
for(int i=0;i<N;i++){
//first we determine the translation with the best feature score for each sentence and each value of x
multimap<float,unsigned> gradient;
vector<float> f0;
for(unsigned j=0;j<FData[i].size();j++){
gradient.insert(pair<float,unsigned>(direction*FData->get(i).get(j),j));
f0[j]=start*FData->get(i).get(j);
}
//now lets compute the 1best for each value of x
unsigned lastindex=gradient.rbegin()->second;
onebest[i].push_back(pair<float,unsigned>(numeric_limit<float>::min(),gradient.begin()->second));//first 1best is the lowest gradient.
for(multimap<float,unsigned>::iterator it=gradient.begin();it!=gradient.end();){
map<float,unsigned>::iterator leftmost=it;
float m=it->first;
float b=f0[it->second];
leftmostx=onebest[i].rbegin()->first;
for(multimap<float,unsigned>::iterator it2=it;it2!=gradient.end();it2++){
float curintersect=intersect(m,b,it2->first,f0[it2->second]);
if(curintersect<leftmostx){
//we have found and intersection to the left of the best one.
leftmostx=curintersect;
leftmost=it2;//this is the new reference
}
}
/* Require that the intersection point be at least min_int
to the right of the previous one. If not, we replace the
previous intersection point with this one. Yes, it can even
happen that the new intersection point is slightly to the
left of the old one, because of numerical imprecision. We
don't check that the new point is also min_interval to the
right of the penultimate one. In that case, the points would
switch places in the sort, resulting in a bogus score for
that inteval. */
if((leftmostx-onebest[i].rbegin()->first)<min_int)
onebest[i][onebest[i].size()-1]=pair<float,unsigned>(leftmostx,it2->second);
else
onebest[i].push_back(pair<float,unsigned>(leftmostx,it2->second));
it=it2;
}
}
//now we have a list of threshold and corresponding onebest. for each sentence.
//now we will compute the stat score for each part of the line and extract the best (with respect to stat score)
float curthreshold=numeric_limit<float>::min();
for(k=0;k<N;k++)
cur1best[k]=onebest[k]->second;
statscore best=GetStatScore(cur1best);
do{
float smallestthreshold=curthreshold;
unsigned changeindex=N;
for(k=0;k<N;k++)
}while
};
point SimpleOptimizer::run(const point& init){
assert(dimension==init.size());
point cur=init;
statscore prevscore=FLT_MAX;
statscore bestscore=FLT_MAX;
do{
point best(dimension);
point linebest(dimension);
for(int d=0;d<dimension;d++){
point direction(dimension);
direction[d]=1.0;
statscore curscore=LineOptimize(cur,direction,linebest);//find the minimum on the line
if(curscore<bestscore){
bestscore=curscore;
best=linebest;
}
}
cur=best;//update the current vector with the best result
}while(bestscore-prevscore<eps);
return cur;
}

55
mert/Optimizer.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef OPTIMIZER_H
#define OPTIMIZER_H
#include<vector>
#include "FeatureStats.h"
#include "FeatureData.h"
#include "FeatureArray.h"
#include "scorer.h"
#include "point.h"
typedef float featurescore;
using namespace std;
/**virtual class*/
class Optimizer{
public:
Scorer * scorer;
FeatureData * FData;
/**number of lambda parameters*/
unsigned dimension;
Optimizer(unsigned d):dimension(d),scorer(NULL),FData(NULL){};
void SetScorer(Scorer *S);
void SetFData(FeatureData *F);
~Optimizer(){
delete scorer;
delete FData;
}
/**Number of sentences in the tuning set*/
unsigned N;
/**main function that perform an optimization*/
virtual point run(const point& init);
/**given a set of lambdas, get the nbest for each sentence*/
vector<unsigned> Get1bests(const point& param);
/**given a set of nbests, get the Statistical score*/
statscore Getstatscore(vector<unsigned> nbests){scorer->score(nbests);};
/**given a set of lambdas, get the total statistical score*/
statscore Getstatscore(const point& param){return Getstatscore(Get1bests(param));};
statscore LineOptimize(const point& start,point direction,point& best);//Get the optimal Lambda and the best score in a particular direction from a given point
}
using namespace std;
/**default basic optimizer*/
class SimpleOptimizer: public Optimizer{
private: float eps;
public:
SimpleOptimizer(unsigned dim,float _eps):Optimizer(dim),eps(_eps){};
point run(const point& init);
}
#endif