package info.ephyra.questionanalysis.atype.minorthird.hierarchical; import java.io.Serializable; import java.util.HashMap; import edu.cmu.minorthird.classify.ClassLabel; import edu.cmu.minorthird.classify.Classifier; import edu.cmu.minorthird.classify.Explanation; import edu.cmu.minorthird.classify.Instance; /** * A hierarchy of classifiers. At first, a top-level classifier is applied. * Classifiers for subclasses are selected based on the outcome of previous * classifications. * * @author Justin Betteridge * @version 2008-02-10 */ public class HierarchicalClassifier implements Classifier,Serializable{ private static final long serialVersionUID=1; private HashMap classifiers; private int classLevels; public HierarchicalClassifier(HashMap classifiers,int classLevels){ this.classifiers=classifiers; this.classLevels=classLevels; } private String getNewLabelName(String currentClass,String sublabel,int level){ if(level==0){ return sublabel; } else{ return currentClass+"."+sublabel; } } public ClassLabel classification(Instance instance){ String labelName=""; double weight=1; for(int i=0;i<classLevels;i++){ Classifier currentClassifier=(Classifier)classifiers.get(labelName); ClassLabel currentLabel=currentClassifier.classification(instance); labelName=getNewLabelName(labelName,currentLabel.bestClassName(),i); weight*=currentLabel.bestWeight(); } return new ClassLabel(labelName,weight); } public String explain(Instance instance){ String labelName=""; String explanation=""; for(int i=0;i<classLevels;i++){ Classifier currentClassifier=(Classifier)classifiers.get(labelName); ClassLabel currentLabel=currentClassifier.classification(instance); labelName=getNewLabelName(labelName,currentLabel.bestClassName(),i); explanation+=currentClassifier.explain(instance); } return explanation; } public Explanation getExplanation(Instance instance){ return new Explanation(explain(instance)); } public static String getHierarchicalClassName(String original,int levels,boolean useClassLevels){ if(useClassLevels){ String[] split=original.split("\\."); String classLabelName=split[0]; for(int i=1;i<levels;i++){ if(split.length<=i){ classLabelName+=".DEFAULT"; } else{ classLabelName+="."+split[i]; } } return classLabelName; } else{ return original.replace('.','-'); } } }