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 DependencyParserConfig configuration; 033 private GuideHistory history; 034 private DecisionModel decisionModel = null; 035 private GuideMode guideMode; 036 private FeatureModelManager featureModelManager; 037 private FeatureModel featureModel; 038 private String guideName; 039 040 public SingleGuide(DependencyParserConfig configuration, GuideHistory history, GuideMode guideMode) throws MaltChainedException { 041 setConfiguration(configuration); 042 setHistory(history); 043 setGuideMode(guideMode); 044 initFeatureModelManager(); 045 initHistory(); 046 initFeatureModel(); 047 featureModel.updateCardinality(); 048 } 049 050 public void addInstance(GuideDecision decision) throws MaltChainedException { 051 if (decisionModel == null) { 052 if (decision instanceof SingleDecision) { 053 initDecisionModel((SingleDecision)decision); 054 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) { 055 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0)); 056 } 057 } 058 decisionModel.addInstance(decision); 059 } 060 061 public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException { 062 if (decisionModel != null) { 063 decisionModel.finalizeSentence(dependencyGraph); 064 } 065 } 066 067 public void noMoreInstances() throws MaltChainedException { 068 if (decisionModel != null) { 069 decisionModel.noMoreInstances(); 070 } else { 071 configuration.getConfigLogger().debug("The guide cannot create any models because there is no decision model. "); 072 } 073 } 074 075 public void terminate() throws MaltChainedException { 076 if (decisionModel != null) { 077 decisionModel.terminate(); 078 decisionModel = null; 079 } 080 } 081 082 public void predict(GuideDecision decision) throws MaltChainedException { 083 if (decisionModel == null) { 084 if (decision instanceof SingleDecision) { 085 initDecisionModel((SingleDecision)decision); 086 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) { 087 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0)); 088 } 089 } 090 decisionModel.predict(decision); 091 } 092 093 public FeatureVector predictExtract(GuideDecision decision) throws MaltChainedException { 094 if (decisionModel == null) { 095 if (decision instanceof SingleDecision) { 096 initDecisionModel((SingleDecision)decision); 097 } else if (decision instanceof MultipleDecision && decision.numberOfDecisions() > 0) { 098 initDecisionModel(((MultipleDecision)decision).getSingleDecision(0)); 099 } 100 } 101 return decisionModel.predictExtract(decision); 102 } 103 104 public FeatureVector extract() throws MaltChainedException { 105 return decisionModel.extract(); 106 } 107 108 public boolean predictFromKBestList(GuideDecision decision) throws MaltChainedException { 109 if (decisionModel != null) { 110 return decisionModel.predictFromKBestList(decision); 111 } else { 112 throw new GuideException("The decision model cannot be found. "); 113 } 114 } 115 116 public DecisionModel getDecisionModel() { 117 return decisionModel; 118 } 119 120 public DependencyParserConfig getConfiguration() { 121 return configuration; 122 } 123 124 public GuideHistory getHistory() { 125 return history; 126 } 127 128 public GuideMode getGuideMode() { 129 return guideMode; 130 } 131 132 public FeatureModelManager getFeatureModelManager() { 133 return featureModelManager; 134 } 135 136 protected void setConfiguration(DependencyParserConfig configuration) { 137 this.configuration = configuration; 138 } 139 140 protected void setHistory(GuideHistory actionHistory) { 141 this.history = actionHistory; 142 } 143 144 protected void setGuideMode(GuideMode guideMode) { 145 this.guideMode = guideMode; 146 } 147 148 protected void initHistory() throws MaltChainedException { 149 Class<?> kBestListClass = null; 150 int kBestSize = 1; 151 if (guideMode == ClassifierGuide.GuideMode.CLASSIFY) { 152 kBestListClass = (Class<?>)getConfiguration().getOptionValue("guide", "kbest_type"); 153 kBestSize = ((Integer)getConfiguration().getOptionValue("guide", "kbest")).intValue(); 154 } 155 history.setKBestListClass(kBestListClass); 156 history.setKBestSize(kBestSize); 157 history.setSeparator(getConfiguration().getOptionValue("guide", "classitem_separator").toString()); 158 } 159 160 protected void initDecisionModel(SingleDecision decision) throws MaltChainedException { 161 Class<?> decisionModelClass = null; 162 if (decision.getRelationToNextDecision() == RelationToNextDecision.SEQUANTIAL) { 163 decisionModelClass = org.maltparser.parser.guide.decision.SeqDecisionModel.class; 164 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.BRANCHED) { 165 decisionModelClass = org.maltparser.parser.guide.decision.BranchedDecisionModel.class; 166 } else if (decision.getRelationToNextDecision() == RelationToNextDecision.NONE) { 167 decisionModelClass = org.maltparser.parser.guide.decision.OneDecisionModel.class; 168 } 169 170 if (decisionModelClass == null) { 171 throw new GuideException("Could not find an appropriate decision model for the relation to the next decision"); 172 } 173 174 try { 175 Class<?>[] argTypes = { org.maltparser.parser.guide.ClassifierGuide.class, org.maltparser.core.feature.FeatureModel.class }; 176 Object[] arguments = new Object[2]; 177 arguments[0] = this; 178 arguments[1] = featureModel; 179 Constructor<?> constructor = decisionModelClass.getConstructor(argTypes); 180 decisionModel = (DecisionModel)constructor.newInstance(arguments); 181 } catch (NoSuchMethodException e) { 182 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 183 } catch (InstantiationException e) { 184 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 185 } catch (IllegalAccessException e) { 186 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 187 } catch (InvocationTargetException e) { 188 throw new GuideException("The decision model class '"+decisionModelClass.getName()+"' cannot be initialized. ", e); 189 } 190 } 191 192 protected void initFeatureModelManager() throws MaltChainedException { 193 final FeatureEngine system = new FeatureEngine(); 194 system.load("/appdata/features/ParserFeatureSystem.xml"); 195 system.load(PluginLoader.instance()); 196 featureModelManager = new FeatureModelManager(system, getConfiguration().getConfigurationDir()); 197 } 198 199 protected void initFeatureModel() throws MaltChainedException { 200 String featureModelFileName = getConfiguration().getOptionValue("guide", "features").toString().trim(); 201 if (featureModelFileName.endsWith(".par")) { 202 featureModelManager.loadSpecification(featureModelFileName); 203 } else { 204 // boolean malt04 = (Boolean)getConfiguration().getOptionValue("malt0.4", "behavior"); 205 boolean malt04 = false; 206 String markingStrategy = getConfiguration().getOptionValue("pproj", "marking_strategy").toString().trim(); 207 String coveredRoot = getConfiguration().getOptionValue("pproj", "covered_root").toString().trim(); 208 featureModelManager.loadParSpecification(featureModelFileName, malt04, markingStrategy, coveredRoot); 209 } 210 // getFeatureModelManager().loadSpecification(getConfiguration().getOptionValue("guide", "features").toString()); 211 if (getConfiguration().getConfigLogger().isInfoEnabled()) { 212 getConfiguration().getConfigLogger().info(" Feature model : " + getConfiguration().getOptionValue("guide", "features").toString()+"\n"); 213 if (getGuideMode() == ClassifierGuide.GuideMode.BATCH) { 214 getConfiguration().getConfigLogger().info(" Learner : " + getConfiguration().getOptionValueString("guide", "learner").toString()+"\n"); 215 } else { 216 getConfiguration().getConfigLogger().info(" Classifier : " + getConfiguration().getOptionValueString("guide", "learner")+"\n"); 217 } 218 } 219 featureModel = getFeatureModelManager().getFeatureModel(getConfiguration().getOptionValue("guide", "features").toString(), 0, getConfiguration().getRegistry()); 220 if (getGuideMode() == ClassifierGuide.GuideMode.BATCH && getConfiguration().getConfigurationDir().getInfoFileWriter() != null) { 221 try { 222 getConfiguration().getConfigurationDir().getInfoFileWriter().write("\nFEATURE MODEL\n"); 223 getConfiguration().getConfigurationDir().getInfoFileWriter().write(featureModel.toString()); 224 getConfiguration().getConfigurationDir().getInfoFileWriter().flush(); 225 } catch (IOException e) { 226 throw new GuideException("Could not write feature model specification to configuration information file. ", e); 227 } 228 } 229 } 230 231 232 public String getGuideName() { 233 return guideName; 234 } 235 236 public void setGuideName(String guideName) { 237 this.guideName = guideName; 238 } 239 240 public String toString() { 241 final StringBuilder sb = new StringBuilder(); 242 return sb.toString(); 243 } 244 }