MOA 12.03
Real Time Analytics for Data Streams
STAGGERGenerator.java
Go to the documentation of this file.
00001 /*
00002  *    STAGGERGenerator.java
00003  *    Copyright (C) 2008 University of Waikato, Hamilton, New Zealand
00004  *    @author Albert Bifet (abifet at cs dot waikato dot ac dot nz)
00005  *
00006  *    This program is free software; you can redistribute it and/or modify
00007  *    it under the terms of the GNU General Public License as published by
00008  *    the Free Software Foundation; either version 3 of the License, or
00009  *    (at your option) any later version.
00010  *
00011  *    This program is distributed in the hope that it will be useful,
00012  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *    GNU General Public License for more details.
00015  *
00016  *    You should have received a copy of the GNU General Public License
00017  *    along with this program. If not, see <http://www.gnu.org/licenses/>.
00018  *    
00019  */
00020 package moa.streams.generators;
00021 
00022 import weka.core.Attribute;
00023 import weka.core.DenseInstance;
00024 import weka.core.FastVector;
00025 import weka.core.Instance;
00026 import weka.core.Instances;
00027 
00028 import java.util.Random;
00029 
00030 import moa.core.InstancesHeader;
00031 import moa.core.ObjectRepository;
00032 import moa.options.AbstractOptionHandler;
00033 import moa.options.FlagOption;
00034 import moa.options.IntOption;
00035 import moa.streams.InstanceStream;
00036 import moa.tasks.TaskMonitor;
00037 
00052 public class STAGGERGenerator extends AbstractOptionHandler implements
00053         InstanceStream {
00054 
00055     @Override
00056     public String getPurposeString() {
00057         return "Generates STAGGER Concept functions.";
00058     }
00059 
00060     private static final long serialVersionUID = 1L;
00061 
00062     public IntOption instanceRandomSeedOption = new IntOption(
00063             "instanceRandomSeed", 'i',
00064             "Seed for random generation of instances.", 1);
00065 
00066     public IntOption functionOption = new IntOption("function", 'f',
00067             "Classification function used, as defined in the original paper.",
00068             1, 1, 3);
00069 
00070     public FlagOption balanceClassesOption = new FlagOption("balanceClasses",
00071             'b', "Balance the number of instances of each class.");
00072 
00073     protected interface ClassFunction {
00074 
00075         public int determineClass(int size, int color, int shape);
00076     }
00077 
00078     protected static ClassFunction[] classificationFunctions = {
00079         // function 1
00080         new ClassFunction() {
00081 
00082     @Override
00083     public int determineClass(int size, int color, int shape) {
00084         return (size == 0 && color == 0) ? 0 : 1; //size==small && color==red
00085     }
00086 },
00087         // function 2
00088         new ClassFunction() {
00089 
00090     @Override
00091     public int determineClass(int size, int color, int shape) {
00092         return (color == 2 || shape == 1) ? 0 : 1; //color==green || shape==circle
00093     }
00094 },
00095         // function 3
00096         new ClassFunction() {
00097 
00098     @Override
00099     public int determineClass(int size, int color, int shape) {
00100         return (size == 1 || size == 2) ? 0 : 1; // size==medium || size==large
00101     }
00102 }
00103     };
00104 
00105     protected InstancesHeader streamHeader;
00106 
00107     protected Random instanceRandom;
00108 
00109     protected boolean nextClassShouldBeZero;
00110 
00111     @Override
00112     protected void prepareForUseImpl(TaskMonitor monitor,
00113             ObjectRepository repository) {
00114         // generate header
00115         FastVector attributes = new FastVector();
00116 
00117         FastVector sizeLabels = new FastVector();
00118         sizeLabels.addElement("small");
00119         sizeLabels.addElement("medium");
00120         sizeLabels.addElement("large");
00121         attributes.addElement(new Attribute("size", sizeLabels));
00122 
00123         FastVector colorLabels = new FastVector();
00124         colorLabels.addElement("red");
00125         colorLabels.addElement("blue");
00126         colorLabels.addElement("green");
00127         attributes.addElement(new Attribute("color", colorLabels));
00128 
00129         FastVector shapeLabels = new FastVector();
00130         shapeLabels.addElement("circle");
00131         shapeLabels.addElement("square");
00132         shapeLabels.addElement("triangle");
00133         attributes.addElement(new Attribute("shape", shapeLabels));
00134 
00135         FastVector classLabels = new FastVector();
00136         classLabels.addElement("false");
00137         classLabels.addElement("true");
00138         attributes.addElement(new Attribute("class", classLabels));
00139         this.streamHeader = new InstancesHeader(new Instances(
00140                 getCLICreationString(InstanceStream.class), attributes, 0));
00141         this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1);
00142         restart();
00143     }
00144 
00145     @Override
00146     public long estimatedRemainingInstances() {
00147         return -1;
00148     }
00149 
00150     @Override
00151     public InstancesHeader getHeader() {
00152         return this.streamHeader;
00153     }
00154 
00155     @Override
00156     public boolean hasMoreInstances() {
00157         return true;
00158     }
00159 
00160     @Override
00161     public boolean isRestartable() {
00162         return true;
00163     }
00164 
00165     @Override
00166     public Instance nextInstance() {
00167 
00168         int size = 0, color = 0, shape = 0, group = 0;
00169         boolean desiredClassFound = false;
00170         while (!desiredClassFound) {
00171             // generate attributes
00172             size = this.instanceRandom.nextInt(3);
00173             color = this.instanceRandom.nextInt(3);
00174             shape = this.instanceRandom.nextInt(3);
00175 
00176             // determine class
00177             group = classificationFunctions[this.functionOption.getValue() - 1].determineClass(size, color, shape);
00178             if (!this.balanceClassesOption.isSet()) {
00179                 desiredClassFound = true;
00180             } else {
00181                 // balance the classes
00182                 if ((this.nextClassShouldBeZero && (group == 0))
00183                         || (!this.nextClassShouldBeZero && (group == 1))) {
00184                     desiredClassFound = true;
00185                     this.nextClassShouldBeZero = !this.nextClassShouldBeZero;
00186                 } // else keep searching
00187             }
00188         }
00189 
00190         // construct instance
00191         InstancesHeader header = getHeader();
00192         Instance inst = new DenseInstance(header.numAttributes());
00193         inst.setValue(0, size);
00194         inst.setValue(1, color);
00195         inst.setValue(2, shape);
00196         inst.setDataset(header);
00197         inst.setClassValue(group);
00198         return inst;
00199     }
00200 
00201     @Override
00202     public void restart() {
00203         this.instanceRandom = new Random(this.instanceRandomSeedOption.getValue());
00204         this.nextClassShouldBeZero = false;
00205     }
00206 
00207     @Override
00208     public void getDescription(StringBuilder sb, int indent) {
00209         // TODO Auto-generated method stub
00210     }
00211 }
 All Classes Namespaces Files Functions Variables Enumerations