MOA 12.03
Real Time Analytics for Data Streams
SEAGenerator.java
Go to the documentation of this file.
00001 /*
00002  *    SEAGenerator.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 SEAGenerator extends AbstractOptionHandler implements
00053         InstanceStream {
00054 
00055     @Override
00056     public String getPurposeString() {
00057         return "Generates SEA concepts functions.";
00058     }
00059 
00060     private static final long serialVersionUID = 1L;
00061 
00062     public IntOption functionOption = new IntOption("function", 'f',
00063             "Classification function used, as defined in the original paper.",
00064             1, 1, 4);
00065 
00066     public IntOption instanceRandomSeedOption = new IntOption(
00067             "instanceRandomSeed", 'i',
00068             "Seed for random generation of instances.", 1);
00069 
00070     public FlagOption balanceClassesOption = new FlagOption("balanceClasses",
00071             'b', "Balance the number of instances of each class.");
00072 
00073     public IntOption numInstancesConcept = new IntOption("numInstancesConcept", 'n',
00074             "The number of instances for each concept.", 0, 0, Integer.MAX_VALUE);
00075 
00076     public IntOption noisePercentageOption = new IntOption("noisePercentage",
00077             'n', "Percentage of noise to add to the data.", 10, 0, 100);
00078 
00079     protected interface ClassFunction {
00080 
00081         public int determineClass(double attrib1, double attrib2, double attrib3);
00082     }
00083 
00084     protected static ClassFunction[] classificationFunctions = {
00085         // function 1
00086         new ClassFunction() {
00087 
00088     @Override
00089     public int determineClass(double attrib1, double attrib2, double attrib3) {
00090         return (attrib1 + attrib2 <= 8) ? 0 : 1;
00091     }
00092 },
00093         // function 2
00094         new ClassFunction() {
00095 
00096     @Override
00097     public int determineClass(double attrib1, double attrib2, double attrib3) {
00098         return (attrib1 + attrib2 <= 9) ? 0 : 1;
00099     }
00100 },
00101         // function 3
00102         new ClassFunction() {
00103 
00104     public int determineClass(double attrib1, double attrib2, double attrib3) {
00105         return (attrib1 + attrib2 <= 7) ? 0 : 1;
00106     }
00107 },
00108         // function 4
00109         new ClassFunction() {
00110 
00111     @Override
00112     public int determineClass(double attrib1, double attrib2, double attrib3) {
00113         return (attrib1 + attrib2 <= 9.5) ? 0 : 1;
00114     }
00115 }
00116     };
00117 
00118     protected InstancesHeader streamHeader;
00119 
00120     protected Random instanceRandom;
00121 
00122     protected boolean nextClassShouldBeZero;
00123 
00124     @Override
00125     protected void prepareForUseImpl(TaskMonitor monitor,
00126             ObjectRepository repository) {
00127         // generate header
00128         FastVector attributes = new FastVector();
00129         attributes.addElement(new Attribute("attrib1"));
00130         attributes.addElement(new Attribute("attrib2"));
00131         attributes.addElement(new Attribute("attrib3"));
00132 
00133         FastVector classLabels = new FastVector();
00134         classLabels.addElement("groupA");
00135         classLabels.addElement("groupB");
00136         attributes.addElement(new Attribute("class", classLabels));
00137         this.streamHeader = new InstancesHeader(new Instances(
00138                 getCLICreationString(InstanceStream.class), attributes, 0));
00139         this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1);
00140         restart();
00141     }
00142 
00143     @Override
00144     public long estimatedRemainingInstances() {
00145         return -1;
00146     }
00147 
00148     @Override
00149     public InstancesHeader getHeader() {
00150         return this.streamHeader;
00151     }
00152 
00153     @Override
00154     public boolean hasMoreInstances() {
00155         return true;
00156     }
00157 
00158     @Override
00159     public boolean isRestartable() {
00160         return true;
00161     }
00162 
00163     @Override
00164     public Instance nextInstance() {
00165         double attrib1 = 0, attrib2 = 0, attrib3 = 0;
00166         int group = 0;
00167         boolean desiredClassFound = false;
00168         while (!desiredClassFound) {
00169             // generate attributes
00170             attrib1 = 10 * this.instanceRandom.nextDouble();
00171             attrib2 = 10 * this.instanceRandom.nextDouble();
00172             attrib3 = 10 * this.instanceRandom.nextDouble();
00173 
00174             // determine class
00175             group = classificationFunctions[this.functionOption.getValue() - 1].determineClass(attrib1, attrib2, attrib3);
00176             if (!this.balanceClassesOption.isSet()) {
00177                 desiredClassFound = true;
00178             } else {
00179                 // balance the classes
00180                 if ((this.nextClassShouldBeZero && (group == 0))
00181                         || (!this.nextClassShouldBeZero && (group == 1))) {
00182                     desiredClassFound = true;
00183                     this.nextClassShouldBeZero = !this.nextClassShouldBeZero;
00184                 } // else keep searching
00185             }
00186         }
00187         //Add Noise
00188         if ((1 + (this.instanceRandom.nextInt(100))) <= this.noisePercentageOption.getValue()) {
00189             group = (group == 0 ? 1 : 0);
00190         }
00191 
00192         // construct instance
00193         InstancesHeader header = getHeader();
00194         Instance inst = new DenseInstance(header.numAttributes());
00195         inst.setValue(0, attrib1);
00196         inst.setValue(1, attrib2);
00197         inst.setValue(2, attrib3);
00198         inst.setDataset(header);
00199         inst.setClassValue(group);
00200         return inst;
00201     }
00202 
00203     @Override
00204     public void restart() {
00205         this.instanceRandom = new Random(this.instanceRandomSeedOption.getValue());
00206         this.nextClassShouldBeZero = false;
00207     }
00208 
00209     @Override
00210     public void getDescription(StringBuilder sb, int indent) {
00211         // TODO Auto-generated method stub
00212     }
00213 }
 All Classes Namespaces Files Functions Variables Enumerations