mosesdecoder/mert/extractor.cpp
Matous Machacek ba987c94ba Support for using factors in mert and evaluator
example:
Use --factor "0|2" to use only first and third factor from nbest list and from reference.
If you use interpolated scorer, separate records with comma (e.g. --factor "0|2,1").
2012-02-28 02:27:23 +01:00

229 lines
6.4 KiB
C++

/**
* Extract features and score statistics from nvest file, optionally merging with
* those from the previous iteration.
* Developed during the 2nd MT marathon.
**/
#include <iostream>
#include <string>
#include <vector>
#include <getopt.h>
#include "Data.h"
#include "Scorer.h"
#include "ScorerFactory.h"
#include "Timer.h"
#include "Util.h"
using namespace std;
namespace {
void usage()
{
cerr << "usage: extractor [options])" << endl;
cerr << "[--sctype|-s] the scorer type (default BLEU)" << endl;
cerr << "[--scconfig|-c] configuration string passed to scorer" << endl;
cerr << "\tThis is of the form NAME1:VAL1,NAME2:VAL2 etc " << endl;
cerr << "[--factors|-f] list of factors passed to the scorer (e.g. 0|2)" << endl;
cerr << "[--reference|-r] comma separated list of reference files" << endl;
cerr << "[--binary|-b] use binary output format (default to text )" << endl;
cerr << "[--nbest|-n] the nbest file" << endl;
cerr << "[--scfile|-S] the scorer data output file" << endl;
cerr << "[--ffile|-F] the feature data output file" << endl;
cerr << "[--prev-ffile|-E] comma separated list of previous feature data" << endl;
cerr << "[--prev-scfile|-R] comma separated list of previous scorer data" << endl;
cerr << "[-v] verbose level" << endl;
cerr << "[--help|-h] print this message and exit" << endl;
exit(1);
}
static struct option long_options[] = {
{"sctype", required_argument, 0, 's'},
{"scconfig", required_argument,0, 'c'},
{"factors", required_argument,0, 'f'},
{"reference", required_argument, 0, 'r'},
{"binary", no_argument, 0, 'b'},
{"nbest", required_argument, 0, 'n'},
{"scfile", required_argument, 0, 'S'},
{"ffile", required_argument, 0, 'F'},
{"prev-scfile", required_argument, 0, 'R'},
{"prev-ffile", required_argument, 0, 'E'},
{"verbose", required_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
// Command line options used in extractor.
struct ProgramOption {
string scorerType;
string scorerConfig;
string scorerFactors;
string referenceFile;
string nbestFile;
string scoreDataFile;
string featureDataFile;
string prevScoreDataFile;
string prevFeatureDataFile;
bool binmode;
int verbosity;
ProgramOption()
: scorerType("BLEU"),
scorerConfig(""),
scorerFactors(""),
referenceFile(""),
nbestFile(""),
scoreDataFile("statscore.data"),
featureDataFile("features.data"),
prevScoreDataFile(""),
prevFeatureDataFile(""),
binmode(false),
verbosity(0) { }
};
void ParseCommandOptions(int argc, char** argv, ProgramOption* opt) {
int c;
int option_index;
while ((c = getopt_long(argc, argv, "s:r:f:n:S:F:R:E:v:hb", long_options, &option_index)) != -1) {
switch (c) {
case 's':
opt->scorerType = string(optarg);
break;
case 'c':
opt->scorerConfig = string(optarg);
break;
case 'f':
opt->scorerFactors = string(optarg);
break;
case 'r':
opt->referenceFile = string(optarg);
break;
case 'b':
opt->binmode = true;
break;
case 'n':
opt->nbestFile = string(optarg);
break;
case 'S':
opt->scoreDataFile = string(optarg);
break;
case 'F':
opt->featureDataFile = string(optarg);
break;
case 'E':
opt->prevFeatureDataFile = string(optarg);
break;
case 'R':
opt->prevScoreDataFile = string(optarg);
break;
case 'v':
opt->verbosity = atoi(optarg);
break;
default:
usage();
}
}
}
} // anonymous namespace
int main(int argc, char** argv)
{
ResetUserTime();
ProgramOption option;
ParseCommandOptions(argc, argv, &option);
try {
// check whether score statistics file is specified
if (option.scoreDataFile.length() == 0) {
throw runtime_error("Error: output score statistics file is not specified");
}
// check wheter feature file is specified
if (option.featureDataFile.length() == 0) {
throw runtime_error("Error: output feature file is not specified");
}
// check whether reference file is specified when nbest is specified
if ((option.nbestFile.length() > 0 && option.referenceFile.length() == 0)) {
throw runtime_error("Error: reference file is not specified; you can not score the nbest");
}
vector<string> nbestFiles;
if (option.nbestFile.length() > 0) {
Tokenize(option.nbestFile.c_str(), ',', &nbestFiles);
}
vector<string> referenceFiles;
if (option.referenceFile.length() > 0) {
Tokenize(option.referenceFile.c_str(), ',', &referenceFiles);
}
vector<string> prevScoreDataFiles;
if (option.prevScoreDataFile.length() > 0) {
Tokenize(option.prevScoreDataFile.c_str(), ',', &prevScoreDataFiles);
}
vector<string> prevFeatureDataFiles;
if (option.prevFeatureDataFile.length() > 0) {
Tokenize(option.prevFeatureDataFile.c_str(), ',', &prevFeatureDataFiles);
}
if (prevScoreDataFiles.size() != prevFeatureDataFiles.size()) {
throw runtime_error("Error: there is a different number of previous score and feature files");
}
if (option.binmode) {
cerr << "Binary write mode is selected" << endl;
} else {
cerr << "Binary write mode is NOT selected" << endl;
}
TRACE_ERR("Scorer type: " << option.scorerType << endl);
Scorer* scorer = ScorerFactory::getScorer(option.scorerType, option.scorerConfig);
scorer->setFactors(option.scorerFactors);
// load references
if (referenceFiles.size() > 0)
scorer->setReferenceFiles(referenceFiles);
PrintUserTime("References loaded");
Data data(*scorer);
// load old data
for (size_t i = 0; i < prevScoreDataFiles.size(); i++) {
data.load(prevFeatureDataFiles.at(i), prevScoreDataFiles.at(i));
}
PrintUserTime("Previous data loaded");
// computing score statistics of each nbest file
for (size_t i = 0; i < nbestFiles.size(); i++) {
data.loadnbest(nbestFiles.at(i));
}
PrintUserTime("Nbest entries loaded and scored");
//ADDED_BY_TS
data.remove_duplicates();
//END_ADDED
data.save(option.featureDataFile, option.scoreDataFile, option.binmode);
PrintUserTime("Stopping...");
delete scorer;
return EXIT_SUCCESS;
} catch (const exception& e) {
cerr << "Exception: " << e.what() << endl;
return EXIT_FAILURE;
}
}