MOA 12.03
Real Time Analytics for Data Streams
|
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 }