MOA 12.03
Real Time Analytics for Data Streams
ConceptDriftRealStream.java
Go to the documentation of this file.
00001 /*
00002  *    ConceptDriftRealStream.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;
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.ClassOption;
00034 import moa.options.FloatOption;
00035 import moa.options.IntOption;
00036 import moa.tasks.TaskMonitor;
00037 
00056 public class ConceptDriftRealStream extends AbstractOptionHandler implements
00057         InstanceStream {
00058 
00059     @Override
00060     public String getPurposeString() {
00061         return "Adds Concept Drift to examples in a stream.";
00062     }
00063 
00064     private static final long serialVersionUID = 1L;
00065 
00066     public ClassOption streamOption = new ClassOption("stream", 's',
00067             "Stream to add concept drift.", InstanceStream.class,
00068             "generators.RandomTreeGenerator");
00069 
00070     public ClassOption driftstreamOption = new ClassOption("driftstream", 'd',
00071             "Concept drift Stream.", InstanceStream.class,
00072             "generators.RandomTreeGenerator");
00073 
00074     public FloatOption alphaOption = new FloatOption("alpha",
00075             'a', "Angle alpha of change grade.", 0.0, 0.0, 90.0);
00076 
00077     public IntOption positionOption = new IntOption("position",
00078             'p', "Central position of concept drift change.", 0);
00079 
00080     public IntOption widthOption = new IntOption("width",
00081             'w', "Width of concept drift change.", 1000);
00082 
00083     public IntOption randomSeedOption = new IntOption("randomSeed", 'r',
00084             "Seed for random noise.", 1);
00085 
00086     protected InstanceStream inputStream;
00087 
00088     protected InstanceStream driftStream;
00089 
00090     protected Random random;
00091 
00092     protected int numberInstanceStream;
00093 
00094     protected InstancesHeader streamHeader;
00095 
00096     protected Instance inputInstance;
00097 
00098     protected Instance driftInstance;
00099 
00100     @Override
00101     public void prepareForUseImpl(TaskMonitor monitor,
00102             ObjectRepository repository) {
00103 
00104         this.inputStream = (InstanceStream) getPreparedClassOption(this.streamOption);
00105         this.driftStream = (InstanceStream) getPreparedClassOption(this.driftstreamOption);
00106         this.random = new Random(this.randomSeedOption.getValue());
00107         numberInstanceStream = 0;
00108         if (this.alphaOption.getValue() != 0.0) {
00109             this.widthOption.setValue((int) (1 / Math.tan(this.alphaOption.getValue() * Math.PI / 180)));
00110         }
00111 
00112         // generate header
00113         Instances first = this.inputStream.getHeader();
00114         Instances second = this.driftStream.getHeader();
00115         FastVector newAttributes = new FastVector();
00116         for (int i = 0; i < first.numAttributes() - 1; i++) {
00117             newAttributes.addElement(first.attribute(i));
00118         }
00119         for (int i = 0; i < second.numAttributes() - 1; i++) {
00120             newAttributes.addElement(second.attribute(i));
00121         }
00122 
00123 
00124         Attribute classLabels;
00125         if (first.numClasses() < second.numClasses()) {
00126             classLabels = second.classAttribute();
00127         } else {
00128             classLabels = first.classAttribute();
00129         }
00130         newAttributes.addElement(classLabels);
00131 
00132         this.streamHeader = new InstancesHeader(new Instances(
00133                 getCLICreationString(InstanceStream.class), newAttributes, 0));
00134         this.streamHeader.setClassIndex(this.streamHeader.numAttributes() - 1);
00135         restart();
00136 
00137     }
00138 
00139     @Override
00140     public long estimatedRemainingInstances() {
00141         return -1;
00142     }
00143 
00144     @Override
00145     public boolean hasMoreInstances() {
00146         return true;
00147     }
00148 
00149     @Override
00150     public InstancesHeader getHeader() {
00151         return this.streamHeader;
00152     }
00153 
00154     @Override
00155     public boolean isRestartable() {
00156         return (this.inputStream.isRestartable() && this.driftStream.isRestartable());
00157     }
00158 
00159     @Override
00160     public Instance nextInstance() {
00161         numberInstanceStream++;
00162         double numclass = 0.0;
00163         double x = -4.0 * (double) (numberInstanceStream - this.positionOption.getValue()) / (double) this.widthOption.getValue();
00164         double probabilityDrift = 1.0 / (1.0 + Math.exp(x));
00165         if (this.random.nextDouble() > probabilityDrift) {
00166             if (this.inputStream.hasMoreInstances() == false) {
00167                 this.inputStream.restart();
00168             }
00169             this.inputInstance = this.inputStream.nextInstance();
00170             numclass = this.inputInstance.classValue();
00171         } else {
00172             if (this.driftStream.hasMoreInstances() == false) {
00173                 this.driftStream.restart();
00174             }
00175             this.driftInstance = this.driftStream.nextInstance();
00176             numclass = this.driftInstance.classValue();
00177         }
00178         int m = 0;
00179         double[] newVals = new double[this.inputInstance.numAttributes() + this.driftInstance.numAttributes() - 1];
00180         for (int j = 0; j < this.inputInstance.numAttributes() - 1; j++, m++) {
00181             newVals[m] = this.inputInstance.value(j);
00182         }
00183         for (int j = 0; j < this.driftInstance.numAttributes() - 1; j++, m++) {
00184             newVals[m] = this.driftInstance.value(j);
00185         }
00186         newVals[m] = numclass;
00187         //return new Instance(1.0, newVals);
00188         Instance inst = new DenseInstance(1.0, newVals);
00189         inst.setDataset(this.getHeader());
00190         inst.setClassValue(numclass);
00191         return inst;
00192 
00193     }
00194 
00195     @Override
00196     public void restart() {
00197         this.inputStream.restart();
00198         this.driftStream.restart();
00199         numberInstanceStream = 0;
00200         this.inputInstance = this.inputStream.nextInstance();
00201         this.driftInstance = this.driftStream.nextInstance();
00202     }
00203 
00204     @Override
00205     public void getDescription(StringBuilder sb, int indent) {
00206         // TODO Auto-generated method stub
00207     }
00208 }
 All Classes Namespaces Files Functions Variables Enumerations