001package org.maltparser.core.lw.parser;
002
003
004import java.util.ArrayList;
005
006import org.maltparser.core.exception.MaltChainedException;
007import org.maltparser.core.feature.FeatureVector;
008import org.maltparser.core.feature.value.FeatureValue;
009import org.maltparser.core.feature.value.MultipleFeatureValue;
010import org.maltparser.core.feature.value.SingleFeatureValue;
011import org.maltparser.ml.lib.FeatureList;
012import org.maltparser.ml.lib.FeatureMap;
013import org.maltparser.ml.lib.MaltFeatureNode;
014import org.maltparser.ml.lib.MaltLibModel;
015import org.maltparser.ml.lib.LibException;
016import org.maltparser.parser.history.action.SingleDecision;
017
018/**
019* A lightweight version of org.maltparser.ml.lib.{Lib,LibLinear,LibSvm} and can only predict the next transition.
020* 
021* @author Johan Hall
022*/
023public class LWClassifier {
024        private final FeatureMap featureMap;
025        private final boolean excludeNullValues;
026        private final MaltLibModel model;
027
028        public LWClassifier(McoModel mcoModel, String prefixFileName, boolean _excludeNullValues)  {
029                this.model = (MaltLibModel)mcoModel.getMcoEntryObject(prefixFileName+".moo");
030                this.featureMap = (FeatureMap)mcoModel.getMcoEntryObject(prefixFileName+".map");
031                this.excludeNullValues = _excludeNullValues;
032        }
033        
034        public boolean predict(FeatureVector featureVector, SingleDecision decision, boolean one_prediction) throws MaltChainedException {
035                final ArrayList<MaltFeatureNode> featureList = new ArrayList<MaltFeatureNode>();
036                final int size = featureVector.size();
037                for (int i = 1; i <= size; i++) {
038                        final FeatureValue featureValue = featureVector.getFeatureValue(i-1);   
039                        if (featureValue != null && !(excludeNullValues == true && featureValue.isNullValue())) {
040                                if (!featureValue.isMultiple()) {
041                                        SingleFeatureValue singleFeatureValue = (SingleFeatureValue)featureValue;
042                                        final int index = featureMap.getIndex(i, singleFeatureValue.getIndexCode());
043                                        if (index != -1 && singleFeatureValue.getValue() != 0) {
044                                                featureList.add(new MaltFeatureNode(index,singleFeatureValue.getValue()));                                      
045                                        }
046                                } 
047                                else { 
048                                        for (Integer value : ((MultipleFeatureValue)featureValue).getCodes()) {
049                                                final int v = featureMap.getIndex(i, value);
050                                                if (v != -1) {
051                                                        featureList.add(new MaltFeatureNode(v,1));      
052                                                }
053                                        }
054                                } 
055                        }
056                }
057                try {
058                        if (one_prediction) {
059                                decision.getKBestList().add(model.predict_one(featureList.toArray(new MaltFeatureNode[featureList.size()])));
060                        } else {
061                                decision.getKBestList().addList(model.predict(featureList.toArray(new MaltFeatureNode[featureList.size()])));
062                        }
063                } catch (OutOfMemoryError e) {
064                        throw new LibException("Out of memory. Please increase the Java heap size (-Xmx<size>). ", e);
065                }
066                return true;
067        }
068}