001package org.maltparser.core.lw.parser; 002 003import java.util.Set; 004 005import org.maltparser.core.exception.MaltChainedException; 006import org.maltparser.core.feature.FeatureModel; 007import org.maltparser.core.feature.FeatureVector; 008import org.maltparser.core.feature.value.SingleFeatureValue; 009import org.maltparser.core.helper.HashMap; 010import org.maltparser.parser.history.action.ComplexDecisionAction; 011import org.maltparser.parser.history.action.SingleDecision; 012import org.maltparser.parser.history.container.TableContainer.RelationToNextDecision; 013 014/** 015* A lightweight version of the decision models, the guide model and the instance models located in org.maltparser.parser.guide.{decision,instance} and 016* can only be used in parsing mode. It is also limited to predict at most two decisions. 017* 018* @author Johan Hall 019*/ 020public final class LWDecisionModel { 021 private final String classifierName; 022 private final HashMap<String, LWClassifier> classifiers; 023 024 public LWDecisionModel(McoModel mcoModel, boolean _excludeNullValues, String _classifierName) { 025 this.classifierName = _classifierName; 026 this.classifiers = new HashMap<String, LWClassifier>(); 027 Set<String> mcoEntryObjectKeys = mcoModel.getMcoEntryObjectKeys(); 028 for (String key : mcoEntryObjectKeys) { 029 if (key.endsWith(".moo")) { 030 String prefixFileName = key.substring(0,key.length()-4); 031 classifiers.put(prefixFileName, new LWClassifier(mcoModel, prefixFileName, _excludeNullValues)); 032 } 033 } 034 } 035 036 public boolean predict(FeatureModel featureModel, ComplexDecisionAction decision, boolean one_prediction) throws MaltChainedException { 037 if (decision.numberOfDecisions() > 2) { 038 throw new MaltChainedException("Number of decisions is greater than two, which is unsupported in the light-weight parser (lw.parser)"); 039 } 040 featureModel.update(); 041 boolean success = true; 042 for (int i = 0; i < decision.numberOfDecisions(); i++) { 043 LWClassifier classifier = null; 044 final SingleDecision singleDecision = decision.getSingleDecision(i); 045 final StringBuilder classifierString = new StringBuilder(); 046 047 final StringBuilder decisionModelString = new StringBuilder(); 048 if (singleDecision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) { 049 decisionModelString.append("bdm"); 050 } else if (singleDecision.getRelationToNextDecision() == RelationToNextDecision.SEQUANTIAL) { 051 decisionModelString.append("sdm"); 052 } else { 053 decisionModelString.append("odm"); 054 } 055 decisionModelString.append(i); 056 String decisionSymbol = ""; 057 if (i == 1 && singleDecision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) { 058 decisionSymbol = singleDecision.getDecisionSymbol(); 059 decisionModelString.append(decisionSymbol); 060 } 061 decisionModelString.append('.'); 062 FeatureVector featureVector = featureModel.getFeatureVector(decisionSymbol, singleDecision.getTableContainer().getTableContainerName()); 063 064 if (featureModel.hasDivideFeatureFunction()) { 065 SingleFeatureValue featureValue =(SingleFeatureValue)featureModel.getDivideFeatureFunction().getFeatureValue(); 066 classifierString.append(decisionModelString); 067 classifierString.append(String.format("%03d", featureValue.getIndexCode())); 068 classifierString.append('.'); 069 classifierString.append(classifierName); 070 classifier = classifiers.get(classifierString.toString()); 071 if (classifier != null) { 072 FeatureVector dividefeatureVector = featureModel.getFeatureVector("/" + featureVector.getSpecSubModel().getSubModelName()); 073 success = classifier.predict(dividefeatureVector, singleDecision, one_prediction) && success; 074 continue; 075 } 076 classifierString.setLength(0); 077 } 078 079 classifierString.append(decisionModelString); 080 classifierString.append(classifierName); 081 classifier = classifiers.get(classifierString.toString()); 082 if (classifier != null) { 083 success = classifier.predict(featureVector, singleDecision, one_prediction) && success; 084 } else { 085 singleDecision.addDecision(1); 086 } 087 if (!singleDecision.continueWithNextDecision()) { 088 break; 089 } 090 } 091 return success; 092 } 093 094 public boolean predictFromKBestList(FeatureModel featureModel, ComplexDecisionAction decision) throws MaltChainedException { 095 predict(featureModel, decision, false); 096 if (decision.numberOfDecisions() == 1) { 097 return decision.getSingleDecision(0).updateFromKBestList(); 098 } else if (decision.numberOfDecisions() > 2) { 099 throw new MaltChainedException("Number of decisions is greater than two, which is unsupported in the light-weight parser (lw.parser)"); 100 } 101 boolean success = false; 102 if (decision.getSingleDecision(0).continueWithNextDecision()) { 103 success = decision.getSingleDecision(1).updateFromKBestList(); 104 } 105 return success; 106 } 107}