00001 #include "TargetConstituentAdjacencyFeature.h"
00002 #include "moses/PP/TargetConstituentBoundariesRightAdjacentPhraseProperty.h"
00003 #include "moses/PP/TargetConstituentBoundariesLeftPhraseProperty.h"
00004 #include "moses/StaticData.h"
00005 #include "moses/ScoreComponentCollection.h"
00006 #include "moses/Hypothesis.h"
00007 #include "moses/FactorCollection.h"
00008 #include "moses/TreeInput.h"
00009 #include <algorithm>
00010
00011
00012 using namespace std;
00013
00014 namespace Moses
00015 {
00016
00017 size_t TargetConstituentAdjacencyFeatureState::hash() const
00018 {
00019 if (m_recombine) {
00020 return 0;
00021 }
00022 size_t ret = 0;
00023 boost::hash_combine(ret, m_collection.size());
00024 for (std::map<const Factor*, float>::const_iterator it=m_collection.begin();
00025 it!=m_collection.end(); ++it) {
00026 boost::hash_combine(ret, it->first);
00027 }
00028 return ret;
00029 };
00030
00031 bool TargetConstituentAdjacencyFeatureState::operator==(const FFState& other) const
00032 {
00033 if (m_recombine) {
00034 return true;
00035 }
00036
00037 if (this == &other) {
00038 return true;
00039 }
00040
00041 const TargetConstituentAdjacencyFeatureState* otherState =
00042 dynamic_cast<const TargetConstituentAdjacencyFeatureState*>(&other);
00043 UTIL_THROW_IF2(otherState == NULL, "Wrong state type");
00044
00045 if (m_collection.size() != (otherState->m_collection).size()) {
00046 return false;
00047 }
00048 std::map<const Factor*, float>::const_iterator thisIt, otherIt;
00049 for (thisIt=m_collection.begin(), otherIt=(otherState->m_collection).begin();
00050 thisIt!=m_collection.end(); ++thisIt, ++otherIt) {
00051 if (thisIt->first != otherIt->first) {
00052 return false;
00053 }
00054 }
00055 return true;
00056 };
00057
00058
00059 TargetConstituentAdjacencyFeature::TargetConstituentAdjacencyFeature(const std::string &line)
00060 : StatefulFeatureFunction(2, line)
00061 , m_featureVariant(0)
00062 , m_recombine(false)
00063 {
00064 VERBOSE(1, "Initializing feature " << GetScoreProducerDescription() << " ...");
00065 ReadParameters();
00066 VERBOSE(1, " Done." << std::endl);
00067 VERBOSE(1, " Feature variant: " << m_featureVariant << "." << std::endl);
00068 }
00069
00070
00071 void TargetConstituentAdjacencyFeature::SetParameter(const std::string& key, const std::string& value)
00072 {
00073 if (key == "variant") {
00074 m_featureVariant = Scan<size_t>(value);
00075 } else if (key == "recombine") {
00076 m_recombine = Scan<bool>(value);
00077 } else {
00078 StatefulFeatureFunction::SetParameter(key, value);
00079 }
00080 }
00081
00082
00083 FFState* TargetConstituentAdjacencyFeature::EvaluateWhenApplied(
00084 const Hypothesis& cur_hypo,
00085 const FFState* prev_state,
00086 ScoreComponentCollection* accumulator) const
00087 {
00088
00089 std::vector<float> newScores(m_numScoreComponents,0);
00090
00091
00092 const TargetConstituentAdjacencyFeatureState *prevState = static_cast<const TargetConstituentAdjacencyFeatureState*>(prev_state);
00093
00094
00095 const TargetPhrase &currTarPhr = cur_hypo.GetCurrTargetPhrase();
00096 FEATUREVERBOSE(2, "Phrase: " << currTarPhr << std::endl);
00097
00098 if (const PhraseProperty *property = currTarPhr.GetProperty("TargetConstituentBoundariesLeft")) {
00099
00100 const TargetConstituentBoundariesLeftPhraseProperty *targetConstituentBoundariesLeftPhraseProperty =
00101 static_cast<const TargetConstituentBoundariesLeftPhraseProperty*>(property);
00102 const TargetConstituentBoundariesLeftCollection& leftConstituentCollection =
00103 targetConstituentBoundariesLeftPhraseProperty->GetCollection();
00104 float prob = 0;
00105 size_t numMatch = 0;
00106 size_t numOverall = 0;
00107
00108 if ( !cur_hypo.GetPrevHypo()->GetPrevHypo() ) {
00109
00110
00111 ++numOverall;
00112 FactorCollection &factorCollection = FactorCollection::Instance();
00113 const Factor* bosFactor = factorCollection.AddFactor("BOS_",false);
00114 TargetConstituentBoundariesLeftCollection::const_iterator found =
00115 leftConstituentCollection.find(bosFactor);
00116 if ( found != leftConstituentCollection.end() ) {
00117 ++numMatch;
00118 prob += found->second;
00119 }
00120
00121 } else {
00122
00123 const std::map<const Factor*, float>& hypConstituentCollection = prevState->m_collection;
00124 std::map<const Factor*, float>::const_iterator iter1 = hypConstituentCollection.begin();
00125 std::map<const Factor*, float>::const_iterator iter2 = leftConstituentCollection.begin();
00126 while ( iter1 != hypConstituentCollection.end() && iter2 != leftConstituentCollection.end() ) {
00127 ++numOverall;
00128 if ( iter1->first < iter2->first ) {
00129 ++iter1;
00130 } else if ( iter2->first < iter1->first ) {
00131 ++iter2;
00132 } else {
00133 ++numMatch;
00134 float currProb = iter1->second * iter2->second;
00135 if (currProb > prob)
00136 prob = currProb;
00137 ++iter1;
00138 ++iter2;
00139 }
00140 }
00141 }
00142
00143 if ( (numMatch == 0) || (prob == 0) ) {
00144 ++newScores[1];
00145 } else {
00146 if ( m_featureVariant == 1 ) {
00147 newScores[0] += TransformScore(prob);
00148 } else {
00149 newScores[0] += TransformScore( (float)numMatch/numOverall );
00150 }
00151 }
00152
00153 } else {
00154
00155
00156 UTIL_THROW_IF2(!currTarPhr.GetWord(0).IsOOV(), GetScoreProducerDescription()
00157 << ": Missing TargetConstituentBoundariesLeft property.");
00158
00159 ++newScores[1];
00160
00161 }
00162
00163 TargetConstituentAdjacencyFeatureState *newState = new TargetConstituentAdjacencyFeatureState(m_recombine);
00164
00165 if (const PhraseProperty *property = currTarPhr.GetProperty("TargetConstituentBoundariesRightAdjacent")) {
00166
00167 const TargetConstituentBoundariesRightAdjacentPhraseProperty *targetConstituentBoundariesRightAdjacentPhraseProperty =
00168 static_cast<const TargetConstituentBoundariesRightAdjacentPhraseProperty*>(property);
00169 const TargetConstituentBoundariesLeftCollection& rightAdjacentConstituentCollection = targetConstituentBoundariesRightAdjacentPhraseProperty->GetCollection();
00170
00171 std::copy(rightAdjacentConstituentCollection.begin(), rightAdjacentConstituentCollection.end(),
00172 std::inserter(newState->m_collection, newState->m_collection.begin()));
00173
00174 } else {
00175
00176
00177 UTIL_THROW_IF2(!currTarPhr.GetWord(0).IsOOV(), GetScoreProducerDescription()
00178 << ": Missing TargetConstituentBoundariesRightAdjacent property.");
00179
00180 }
00181
00182
00183 accumulator->PlusEquals(this, newScores);
00184
00185 return newState;
00186 }
00187
00188 }
00189