    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    }