001    package org.maltparser.parser.guide.decision;
002    
003    import org.maltparser.core.exception.MaltChainedException;
004    import org.maltparser.core.feature.FeatureModel;
005    import org.maltparser.core.feature.FeatureVector;
006    import org.maltparser.core.syntaxgraph.DependencyStructure;
007    import org.maltparser.parser.DependencyParserConfig;
008    import org.maltparser.parser.guide.ClassifierGuide;
009    import org.maltparser.parser.guide.GuideException;
010    import org.maltparser.parser.guide.instance.AtomicModel;
011    import org.maltparser.parser.guide.instance.FeatureDivideModel;
012    import org.maltparser.parser.guide.instance.InstanceModel;
013    import org.maltparser.parser.history.action.GuideDecision;
014    import org.maltparser.parser.history.action.MultipleDecision;
015    import org.maltparser.parser.history.action.SingleDecision;
016    /**
017    *
018    * @author Johan Hall
019    * @since 1.1
020    **/
021    public class OneDecisionModel implements DecisionModel {
022            private final ClassifierGuide guide;
023            private final String modelName;
024            private final FeatureModel featureModel;
025            private final int decisionIndex;
026            private final DecisionModel prevDecisionModel;
027            private final String branchedDecisionSymbols;
028    //      private int nIteration;
029            private InstanceModel instanceModel;
030            
031            public OneDecisionModel(ClassifierGuide guide, FeatureModel featureModel) throws MaltChainedException {
032                    this.branchedDecisionSymbols = "";
033                    this.guide = guide;
034                    this.featureModel = featureModel;
035                    this.decisionIndex = 0;
036                    if (guide.getGuideName() == null || guide.getGuideName().equals("")) {
037                            this.modelName = "odm"+decisionIndex;
038                    } else {
039                            this.modelName = guide.getGuideName()+".odm"+decisionIndex;
040                    }
041                    this.prevDecisionModel = null;
042            }
043            
044            public OneDecisionModel(ClassifierGuide guide, DecisionModel prevDecisionModel, String branchedDecisionSymbol) throws MaltChainedException {
045                    if (branchedDecisionSymbol != null && branchedDecisionSymbol.length() > 0) {
046                            this.branchedDecisionSymbols = branchedDecisionSymbol;
047                    } else {
048                            this.branchedDecisionSymbols = "";
049                    }
050                    this.guide = guide;
051                    this.featureModel = prevDecisionModel.getFeatureModel();
052                    this.decisionIndex = prevDecisionModel.getDecisionIndex() + 1;
053                    this.prevDecisionModel = prevDecisionModel;
054                    if (branchedDecisionSymbols != null && branchedDecisionSymbols.length() > 0) {
055                            this.modelName = "odm"+decisionIndex+branchedDecisionSymbols;
056                    } else {
057                            this.modelName = "odm"+decisionIndex;
058                    }
059            }
060            
061            public void updateFeatureModel() throws MaltChainedException {
062                    featureModel.update();
063            }
064    
065            public void finalizeSentence(DependencyStructure dependencyGraph) throws MaltChainedException {
066                    if (instanceModel != null) {
067                            instanceModel.finalizeSentence(dependencyGraph);
068                    }
069            }
070            
071            public void noMoreInstances() throws MaltChainedException {
072                    if (guide.getGuideMode() == ClassifierGuide.GuideMode.CLASSIFY) {
073                            throw new GuideException("The decision model could not create it's model. ");
074                    }
075    
076                    if (instanceModel != null) {
077                            instanceModel.noMoreInstances();
078                            instanceModel.train();
079                    }
080            }
081    
082            public void terminate() throws MaltChainedException {
083                    if (instanceModel != null) {
084                            instanceModel.terminate();
085                            instanceModel = null;
086                    }
087            }
088            
089            public void addInstance(GuideDecision decision) throws MaltChainedException {
090                    featureModel.update();
091                    final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
092                    
093                    if (instanceModel == null) {
094                            initInstanceModel(singleDecision.getTableContainer().getTableContainerName());
095                    }
096                    instanceModel.addInstance(singleDecision);
097            }
098            
099            public boolean predict(GuideDecision decision) throws MaltChainedException {
100                    featureModel.update();
101                    final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
102    
103                    if (instanceModel == null) {
104                            initInstanceModel(singleDecision.getTableContainer().getTableContainerName());
105                    }
106                    return instanceModel.predict(singleDecision);
107            }
108            
109            public FeatureVector predictExtract(GuideDecision decision) throws MaltChainedException {
110                    featureModel.update();
111                    final SingleDecision singleDecision = (decision instanceof SingleDecision)?(SingleDecision)decision:((MultipleDecision)decision).getSingleDecision(decisionIndex);
112    
113                    if (instanceModel == null) {
114                            initInstanceModel(singleDecision.getTableContainer().getTableContainerName());
115                    }
116                    return instanceModel.predictExtract(singleDecision);
117            }
118            
119            public FeatureVector extract() throws MaltChainedException {
120                    featureModel.update();
121                    return instanceModel.extract();
122            }
123            
124            public boolean predictFromKBestList(GuideDecision decision) throws MaltChainedException {
125                    if (decision instanceof SingleDecision) {
126                            return ((SingleDecision)decision).updateFromKBestList();
127                    } else {
128                            return ((MultipleDecision)decision).getSingleDecision(decisionIndex).updateFromKBestList();
129                    }
130            }
131            
132            public ClassifierGuide getGuide() {
133                    return guide;
134            }
135    
136            public String getModelName() {
137                    return modelName;
138            }
139            
140            public FeatureModel getFeatureModel() {
141                    return featureModel;
142            }
143    
144            public int getDecisionIndex() {
145                    return decisionIndex;
146            }
147    
148            public DecisionModel getPrevDecisionModel() {
149                    return prevDecisionModel;
150            }
151    
152            private final void initInstanceModel(String subModelName) throws MaltChainedException {
153                    FeatureVector fv = featureModel.getFeatureVector(branchedDecisionSymbols+"."+subModelName);
154                    if (fv == null) {
155                            fv = featureModel.getFeatureVector(subModelName);
156                    }
157                    if (fv == null) {
158                            fv = featureModel.getMainFeatureVector();
159                    }
160                    final DependencyParserConfig c = guide.getConfiguration();
161                    if (c.getOptionValue("guide", "data_split_column").toString().length() == 0) {
162                            instanceModel = new AtomicModel(-1, fv, this);
163                    } else {
164                            instanceModel = new FeatureDivideModel(fv, this);
165                    }
166            }
167            
168            public String toString() {              
169                    return modelName;
170            }
171    }