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