001 package org.maltparser.parser.guide;
002
003
004 import java.io.IOException;
005 import java.lang.reflect.Constructor;
006 import java.lang.reflect.InvocationTargetException;
007
008 import org.maltparser.core.exception.MaltChainedException;
009 import org.maltparser.core.feature.FeatureModel;
010 import org.maltparser.core.feature.FeatureModelManager;
011 import org.maltparser.core.feature.FeatureVector;
012 import org.maltparser.core.feature.system.FeatureEngine;
013 import org.maltparser.core.plugin.PluginLoader;
014 import org.maltparser.core.syntaxgraph.DependencyStructure;
015 import org.maltparser.parser.DependencyParserConfig;
016 import org.maltparser.parser.guide.decision.DecisionModel;
017 import org.maltparser.parser.history.GuideHistory;
018 import org.maltparser.parser.history.action.GuideDecision;
019 import org.maltparser.parser.history.action.MultipleDecision;
020 import org.maltparser.parser.history.action.SingleDecision;
021 import org.maltparser.parser.history.container.TableContainer.RelationToNextDecision;
022
023
024 /**
025 * The guide is used by a parsing algorithm to predict the next parser action during parsing and to
026 * add a instance to the training instance set during learning.
027
028 @author Johan Hall
029 @since 1.0
030 */
031 public class SingleGuide implements ClassifierGuide {
032 private final DependencyParserConfig configuration;
033 private final GuideHistory history;
034 private final GuideMode guideMode;
035 private final FeatureModelManager featureModelManager;
036 private final FeatureModel featureModel;
037 private DecisionModel decisionModel = null;
038 private String guideName;
039
040 public SingleGuide(DependencyParserConfig configuration, GuideHistory history, GuideMode guideMode) throws MaltChainedException {
041 this.configuration = configuration;
042
043 this.guideMode = guideMode;
044 final FeatureEngine system = new FeatureEngine();
045 system.load("/appdata/features/ParserFeatureSystem.xml");
046 system.load(PluginLoader.instance());
047 featureModelManager = new FeatureModelManager(system, getConfiguration().getConfigurationDir());
048
049 // initialize history
050 this.history = history;
051 Class<?> kBestListClass = null;
052 int kBestSize = 1;
053 if (guideMode == ClassifierGuide.GuideMode.CLASSIFY) {
054 kBestListClass = (Class<?>)getConfiguration().getOptionValue("guide", "kbest_type");
055 kBestSize = ((Integer)getConfiguration().getOptionValue("guide", "kbest")).intValue();
056 }
057 history.setKBestListClass(kBestListClass);
058 history.setKBestSize(kBestSize);
059 history.setSeparator(getConfiguration().getOptionValue("guide", "classitem_separator").toString());
060
061 // initialize feature model
062 String featureModelFileName = getConfiguration().getOptionValue("guide", "features").toString().trim();
063
064 if (featureModelFileName.endsWith(".par")) {
065 String markingStrategy = getConfiguration().getOptionValue("pproj", "marking_strategy").toString().trim();
066 String coveredRoot = getConfiguration().getOptionValue("pproj", "covered_root").toString().trim();
067 featureModelManager.loadParSpecification(featureModelFileName, markingStrategy, coveredRoot);
068 } else {
069 featureModelManager.loadSpecification(featureModelFileName);
070 }
071 if (getConfiguration().getConfigLogger().isInfoEnabled()) {
072 getConfiguration().getConfigLogger().info(" Feature model : " + featureModelFileName+"\n");
073 if (getGuideMode() == ClassifierGuide.GuideMode.BATCH) {
074 getConfiguration().getConfigLogger().info(" Learner : " + getConfiguration().getOptionValueString("guide", "learner").toString()+"\n");
075 } else {
076 getConfiguration().getConfigLogger().info(" Classifier : " + getConfiguration().getOptionValueString("guide", "learner")+"\n");
077 }
078 }
079 featureModel = getFeatureModelManager().getFeatureModel(getConfiguration().getOptionValue("guide", "features").toString(), 0, getConfiguration().getRegistry());
080 if (getGuideMode() == ClassifierGuide.GuideMode.BATCH && getConfiguration().getConfigurationDir().getInfoFileWriter() != null) {
081 try {
082 getConfiguration().getConfigurationDir().getInfoFileWriter().write("\nFEATURE MODEL\n");
083 getConfiguration().getConfigurationDir().getInfoFileWriter().write(featureModel.toString());
084 getConfiguration().getConfigurationDir().getInfoFileWriter().flush();
085 } catch (IOException e) {
086 throw new GuideException("Could not write feature model specification to configuration information file. ", e);
087 }
088 }
089
090 }
091
092 public void addInstance(GuideDecision decision) throws MaltChainedException {
093 if (decisionModel == null) {
094 if (decision instanceof SingleDecision) {
095 initDecisionModel((SingleDecision)decision);
096 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
097 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
098 }
099 }
100 decisionModel.addInstance(decision);
101 }
102
103 public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {
104 if (decisionModel != null) {
105 decisionModel.finalizeSentence(dependencyGraph);
106 }
107 }
108
109 public void noMoreInstances() throws MaltChainedException {
110 if (decisionModel != null) {
111 decisionModel.noMoreInstances();
112 } else {
113 configuration.getConfigLogger().debug("The guide cannot create any models because there is no decision model. ");
114 }
115 }
116
117 public void terminate() throws MaltChainedException {
118 if (decisionModel != null) {
119 decisionModel.terminate();
120 decisionModel = null;
121 }
122 }
123
124 public void predict(GuideDecision decision) throws MaltChainedException {
125 if (decisionModel == null) {
126 if (decision instanceof SingleDecision) {
127 initDecisionModel((SingleDecision)decision);
128 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
129 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
130 }
131 }
132 decisionModel.predict(decision);
133 }
134
135 public FeatureVector predictExtract(GuideDecision decision) throws MaltChainedException {
136 if (decisionModel == null) {
137 if (decision instanceof SingleDecision) {
138 initDecisionModel((SingleDecision)decision);
139 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) {
140 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0));
141 }
142 }
143 return decisionModel.predictExtract(decision);
144 }
145
146 public FeatureVector extract() throws MaltChainedException {
147 return decisionModel.extract();
148 }
149
150 public boolean predictFromKBestList(GuideDecision decision) throws MaltChainedException {
151 if (decisionModel != null) {
152 return decisionModel.predictFromKBestList(decision);
153 } else {
154 throw new GuideException("The decision model cannot be found. ");
155 }
156 }
157
158 public DecisionModel getDecisionModel() {
159 return decisionModel;
160 }
161
162 public DependencyParserConfig getConfiguration() {
163 return configuration;
164 }
165
166 public GuideHistory getHistory() {
167 return history;
168 }
169
170 public GuideMode getGuideMode() {
171 return guideMode;
172 }
173
174 public FeatureModelManager getFeatureModelManager() {
175 return featureModelManager;
176 }
177
178 protected void initDecisionModel(SingleDecision decision) throws MaltChainedException {
179 Class<?> decisionModelClass = null;
180 if (decision.getRelationToNextDecision() == RelationToNextDecision.SEQUANTIAL) {
181 decisionModelClass = org.maltparser.parser.guide.decision.SeqDecisionModel.class;
182 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) {
183 decisionModelClass = org.maltparser.parser.guide.decision.BranchedDecisionModel.class;
184 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.NONE) {
185 decisionModelClass = org.maltparser.parser.guide.decision.OneDecisionModel.class;
186 }
187
188 if (decisionModelClass == null) {
189 throw new GuideException("Could not find an appropriate decision model for the relation to the next decision");
190 }
191
192 try {
193 Class<?>[] argTypes = { org.maltparser.parser.guide.ClassifierGuide.class, org.maltparser.core.feature.FeatureModel.class };
194 Object[] arguments = new Object[2];
195 arguments[0] = this;
196 arguments[1] = featureModel;
197 Constructor<?> constructor = decisionModelClass.getConstructor(argTypes);
198 decisionModel = (DecisionModel)constructor.newInstance(arguments);
199 } catch (NoSuchMethodException e) {
200 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e);
201 } catch (InstantiationException e) {
202 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e);
203 } catch (IllegalAccessException e) {
204 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e);
205 } catch (InvocationTargetException e) {
206 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e);
207 }
208 }
209
210 public String getGuideName() {
211 return guideName;
212 }
213
214 public void setGuideName(String guideName) {
215 this.guideName = guideName;
216 }
217
218 public String toString() {
219 final StringBuilder sb = new StringBuilder();
220 return sb.toString();
221 }
222 }