MOA 12.03
Real Time Analytics for Data Streams
WEKAClassifier.java
Go to the documentation of this file.
00001 /*
00002  *    WEKAClassifier.java
00003  *    Copyright (C) 2009 University of Waikato, Hamilton, New Zealand
00004  *    @author Albert Bifet (abifet at cs dot waikato dot ac dot nz)
00005  *    @author FracPete (fracpete at waikato dot ac dot nz)
00006  *
00007  *    This program is free software; you can redistribute it and/or modify
00008  *    it under the terms of the GNU General Public License as published by
00009  *    the Free Software Foundation; either version 3 of the License, or
00010  *    (at your option) any later version.
00011  *
00012  *    This program is distributed in the hope that it will be useful,
00013  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *    GNU General Public License for more details.
00016  *
00017  *    You should have received a copy of the GNU General Public License
00018  *    along with this program. If not, see <http://www.gnu.org/licenses/>.
00019  *    
00020  */
00021 package moa.classifiers.meta;
00022 
00023 import moa.classifiers.AbstractClassifier;
00024 import moa.core.Measurement;
00025 import moa.options.IntOption;
00026 import moa.options.WEKAClassOption;
00027 import weka.classifiers.Classifier;
00028 import weka.classifiers.UpdateableClassifier;
00029 import weka.core.Instance;
00030 import weka.core.Instances;
00031 
00039 public class WEKAClassifier
00040         extends AbstractClassifier {
00041 
00042     private static final long serialVersionUID = 1L;
00043 
00044     @Override
00045     public String getPurposeString() {
00046         return "Classifier from Weka";
00047     }
00048     
00049     public WEKAClassOption baseLearnerOption = new WEKAClassOption("baseLearner", 'l',
00050             "Classifier to train.", weka.classifiers.Classifier.class, "weka.classifiers.bayes.NaiveBayesUpdateable");
00051 
00052     public IntOption widthOption = new IntOption("width",
00053             'w', "Size of Window for training learner.", 0, 0, Integer.MAX_VALUE);
00054 
00055     public IntOption widthInitOption = new IntOption("widthInit",
00056             'i', "Size of first Window for training learner.", 1000, 0, Integer.MAX_VALUE);
00057 
00058     public IntOption sampleFrequencyOption = new IntOption("sampleFrequency",
00059             'f',
00060             "How many instances between samples of the learning performance.",
00061             0, 0, Integer.MAX_VALUE);
00062 
00063     protected Classifier classifier;
00064 
00065     protected int numberInstances;
00066 
00067     protected Instances instancesBuffer;
00068 
00069     protected boolean isClassificationEnabled;
00070 
00071     protected boolean isBufferStoring;
00072 
00073     @Override
00074     public void resetLearningImpl() {
00075 
00076         try {
00077             //System.out.println(baseLearnerOption.getValue());
00078             String[] options = weka.core.Utils.splitOptions(baseLearnerOption.getValueAsCLIString());
00079             createWekaClassifier(options);
00080         } catch (Exception e) {
00081             System.err.println("Creating a new classifier: " + e.getMessage());
00082         }
00083         numberInstances = 0;
00084         isClassificationEnabled = false;
00085         this.isBufferStoring = true;
00086     }
00087 
00088     @Override
00089     public void trainOnInstanceImpl(Instance inst) {
00090         try {
00091             if (numberInstances == 0) {
00092                 this.instancesBuffer = new Instances(inst.dataset());
00093                 if (classifier instanceof UpdateableClassifier) {
00094                     classifier.buildClassifier(instancesBuffer);
00095                     this.isClassificationEnabled = true;
00096                 } else {
00097                     this.isBufferStoring = true;
00098                 }
00099             }
00100             numberInstances++;
00101 
00102             if (classifier instanceof UpdateableClassifier) {
00103                 if (numberInstances > 0) {
00104                     ((UpdateableClassifier) classifier).updateClassifier(inst);
00105                 }
00106             } else {
00107                 if (numberInstances == widthInitOption.getValue()) {
00108                     //Build first time Classifier
00109                     buildClassifier();
00110                     isClassificationEnabled = true;
00111                     //Continue to store instances
00112                     if (sampleFrequencyOption.getValue() != 0) {
00113                         isBufferStoring = true;
00114                     }
00115                 }
00116                 if (widthOption.getValue() == 0) {
00117                     //Used from SingleClassifierDrift
00118                     if (isBufferStoring == true) {
00119                         instancesBuffer.add(inst);
00120                     }
00121                 } else {
00122                     //Used form WekaClassifier without using SingleClassifierDrift
00123                     int numInstances = numberInstances % sampleFrequencyOption.getValue();
00124                     if (sampleFrequencyOption.getValue() == 0) {
00125                         numInstances = numberInstances;
00126                     }
00127                     if (numInstances == 0) {
00128                         //Begin to store instances
00129                         isBufferStoring = true;
00130                     }
00131                     if (isBufferStoring == true && numInstances <= widthOption.getValue()) {
00132                         //Store instances
00133                         instancesBuffer.add(inst);
00134                     }
00135                     if (numInstances == widthOption.getValue()) {
00136                         //Build Classifier
00137                         buildClassifier();
00138                         isClassificationEnabled = true;
00139                         this.instancesBuffer = new Instances(inst.dataset());
00140                     }
00141                 }
00142             }
00143         } catch (Exception e) {
00144             System.err.println("Training: " + e.getMessage());
00145         }
00146     }
00147 
00148     public void buildClassifier() {
00149         try {
00150             if ((classifier instanceof UpdateableClassifier) == false) {
00151                 Classifier auxclassifier = weka.classifiers.AbstractClassifier.makeCopy(classifier);
00152                 auxclassifier.buildClassifier(instancesBuffer);
00153                 classifier = auxclassifier;
00154                 isBufferStoring = false;
00155             }
00156         } catch (Exception e) {
00157             System.err.println("Building WEKA Classifier: " + e.getMessage());
00158         }
00159     }
00160 
00161     @Override
00162     public double[] getVotesForInstance(Instance inst) {
00163         double[] votes = new double[inst.numClasses()];
00164         if (isClassificationEnabled == false) {
00165             for (int i = 0; i < inst.numClasses(); i++) {
00166                 votes[i] = 1.0 / inst.numClasses();
00167             }
00168         } else {
00169             try {
00170                 votes = this.classifier.distributionForInstance(inst);
00171             } catch (Exception e) {
00172                 System.err.println(e.getMessage());
00173             }
00174         }
00175         return votes;
00176     }
00177 
00178     @Override
00179     public boolean isRandomizable() {
00180         return false;
00181     }
00182 
00183     @Override
00184     public void getModelDescription(StringBuilder out, int indent) {
00185         if (classifier != null) {
00186             out.append(classifier.toString());
00187         }
00188     }
00189 
00190     @Override
00191     protected Measurement[] getModelMeasurementsImpl() {
00192         Measurement[] m = new Measurement[0];
00193         return m;
00194     }
00195 
00196     public void createWekaClassifier(String[] options) throws Exception {
00197         String classifierName = options[0];
00198         String[] newoptions = options.clone();
00199         newoptions[0] = "";
00200         this.classifier = weka.classifiers.AbstractClassifier.forName(classifierName, newoptions);
00201     }
00202 }
 All Classes Namespaces Files Functions Variables Enumerations