package edu.cmu.minorthird.classify.multi; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import edu.cmu.minorthird.classify.Classifier; import edu.cmu.minorthird.classify.ClassifierLearner; import edu.cmu.minorthird.classify.ClassifierLearnerFactory; import edu.cmu.minorthird.classify.Example; import edu.cmu.minorthird.classify.ExampleSchema; import edu.cmu.minorthird.classify.Instance; import edu.cmu.minorthird.classify.algorithms.linear.MaxEntLearner; /** * ClassifierLearner for learning multiple dimensions * * @author Cameron Williams */ public class MultiLearner implements ClassifierLearner{ protected ClassifierLearnerFactory learnerFactory; protected ClassifierLearner learner; protected String learnerName; protected List<ClassifierLearner> innerLearner; protected MultiExampleSchema multiSchema; public MultiLearner(ClassifierLearner learner){ this.learner=learner; this.learnerName=learner.toString(); } public MultiLearner(){ this(new MaxEntLearner()); } @Override public ClassifierLearner copy(){ MultiLearner learner=null; try{ learner=(MultiLearner)this.clone(); for(int i=0;i<innerLearner.size();i++){ ClassifierLearner inner=innerLearner.get(i); learner.innerLearner.add(inner.copy()); } }catch(Exception e){ e.printStackTrace(); } return learner; } @Override public void setSchema(ExampleSchema schema){ System.err.println("Must use setMultiSchema(MultiExampleSchema schema)"); } @Override public ExampleSchema getSchema(){ return null; } // Strange. Looks like all it does is copying the same learner during setting schema. - frank public void setMultiSchema(MultiExampleSchema schema){ this.multiSchema=schema; innerLearner=new ArrayList<ClassifierLearner>(); ExampleSchema[] schemas=multiSchema.getSchemas(); for(int i=0;i<schemas.length;i++){ innerLearner.add(learner.copy()); innerLearner.get(i).setSchema(schemas[i]); } } public MultiExampleSchema getMultiSchema(){ return multiSchema; } @Override public void reset(){ if(innerLearner!=null){ for(int i=0;i<innerLearner.size();i++){ ((innerLearner.get(i))).reset(); } } } @Override public void setInstancePool(Iterator<Instance> it){ List<Instance> list=new ArrayList<Instance>(); while(it.hasNext()) list.add(it.next()); for(int i=0;i<innerLearner.size();i++){ innerLearner.get(i).setInstancePool(list.iterator()); } } @Override public boolean hasNextQuery(){ for(int i=0;i<innerLearner.size();i++){ if(innerLearner.get(i).hasNextQuery()){ return true; } } return false; } @Override public Instance nextQuery(){ for(int i=0;i<innerLearner.size();i++){ if(innerLearner.get(i).hasNextQuery()){ return innerLearner.get(i).nextQuery(); } } return null; } @Override public void addExample(Example answeredQuery){ System.err.println("Must use addMultiExample(MultiExample answeredQuery)"); } public void addMultiExample(MultiExample answeredQuery){ Example[] examples=answeredQuery.getExamples(); for(int i=0;i<innerLearner.size();i++){ innerLearner.get(i).addExample(examples[i]); } } @Override public void completeTraining(){ for(int i=0;i<innerLearner.size();i++){ innerLearner.get(i).completeTraining(); } } /** Returns the classifier for the first dimension */ @Override public Classifier getClassifier(){ if(innerLearner.get(0)==null){ return null; } else{ return innerLearner.get(0).getClassifier(); } } public MultiClassifier getMultiClassifier(){ Classifier[] classifiers=new Classifier[innerLearner.size()]; for(int i=0;i<innerLearner.size();i++){ classifiers[i]=innerLearner.get(i).getClassifier(); } return new MultiClassifier(classifiers); } }