MOA 12.03
Real Time Analytics for Data Streams
MicroCluster.java
Go to the documentation of this file.
00001 /*
00002  *    MicroCluster.java
00003  *    Copyright (C) 2010 RWTH Aachen University, Germany
00004  *    @author Wels ([email protected])
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 
00021 package moa.clusterers.denstream;
00022 
00023 import moa.cluster.CFCluster;
00024 import weka.core.Instance;
00025 
00026 public class MicroCluster extends CFCluster {
00027 
00028     private long lastEditT = -1;
00029     private long creationTimestamp = -1;
00030     private double lambda;
00031     private Timestamp currentTimestamp;
00032 
00033     public MicroCluster(double[] center, int dimensions, long creationTimestamp, double lambda, Timestamp currentTimestamp) {
00034         super(center, dimensions);
00035         this.creationTimestamp = creationTimestamp;
00036         this.lastEditT = creationTimestamp;
00037         this.lambda = lambda;
00038         this.currentTimestamp = currentTimestamp;
00039     }
00040 
00041     public MicroCluster(Instance instance, int dimensions, long timestamp, double lambda, Timestamp currentTimestamp) {
00042         this(instance.toDoubleArray(), dimensions, timestamp, lambda, currentTimestamp);
00043     }
00044 
00045     public void insert(Instance instance, long timestamp) {
00046         N++;
00047         super.setWeight(super.getWeight() + 1);
00048         this.lastEditT = timestamp;
00049 
00050         for (int i = 0; i < instance.numValues(); i++) {
00051             LS[i] += instance.value(i);
00052             SS[i] += instance.value(i) * instance.value(i);
00053         }
00054     }
00055 
00056     public long getLastEditTimestamp() {
00057         return lastEditT;
00058     }
00059 
00060     private double[] calcCF2(long dt) {
00061         double[] cf2 = new double[SS.length];
00062         for (int i = 0; i < SS.length; i++) {
00063             cf2[i] = Math.pow(2, -lambda * dt) * SS[i];
00064         }
00065         return cf2;
00066     }
00067 
00068     private double[] calcCF1(long dt) {
00069         double[] cf1 = new double[LS.length];
00070         for (int i = 0; i < LS.length; i++) {
00071             cf1[i] = Math.pow(2, -lambda * dt) * LS[i];
00072         }
00073         return cf1;
00074     }
00075 
00076     @Override
00077     public double getWeight() {
00078         return getWeight(currentTimestamp.getTimestamp());
00079     }
00080 
00081     private double getWeight(long timestamp) {
00082         long dt = timestamp - lastEditT;
00083         return (N * Math.pow(2, -lambda * dt));
00084     }
00085 
00086     public long getCreationTime() {
00087         return creationTimestamp;
00088     }
00089 
00090     @Override
00091     public double[] getCenter() {
00092         return getCenter(currentTimestamp.getTimestamp());
00093     }
00094 
00095     private double[] getCenter(long timestamp) {
00096         long dt = timestamp - lastEditT;
00097         double w = getWeight(timestamp);
00098         double[] res = new double[LS.length];
00099         for (int i = 0; i < LS.length; i++) {
00100             res[i] = LS[i];
00101             res[i] *= Math.pow(2, -lambda * dt);
00102             res[i] /= w;
00103         }
00104         return res;
00105     }
00106 
00107     @Override
00108     public double getRadius() {
00109         return getRadius(currentTimestamp.getTimestamp())*radiusFactor;
00110     }
00111 
00112     public double getRadius(long timestamp) {
00113         long dt = timestamp - lastEditT;
00114         double[] cf1 = calcCF1(dt);
00115         double[] cf2 = calcCF2(dt);
00116         double w = getWeight(timestamp);
00117         double max = 0;
00118         double sum = 0;
00119         for (int i = 0; i < SS.length; i++) {
00120             double x1 = cf2[i] / w;
00121             double x2 = Math.pow(cf1[i] / w, 2);
00122             //sum += Math.pow(x1 - x2,2);
00123             sum += (x1 - x2);
00124             if (Math.sqrt(x1 - x2) > max) {
00125                 max = Math.sqrt(x1 - x2);
00126             }
00127         }
00128         return max;
00129     }
00130 
00131     @Override
00132     public MicroCluster copy() {
00133         MicroCluster copy = new MicroCluster(this.LS.clone(), this.LS.length, this.getCreationTime(), this.lambda, this.currentTimestamp);
00134         copy.setWeight(this.N + 1);
00135         copy.N = this.N;
00136         copy.SS = this.SS.clone();
00137         copy.LS = this.LS.clone();
00138         copy.lastEditT = this.lastEditT;
00139         return copy;
00140     }
00141 
00142     @Override
00143     public double getInclusionProbability(Instance instance) {
00144         if (getCenterDistance(instance) <= getRadius()) {
00145             return 1.0;
00146         }
00147         return 0.0;
00148     }
00149 
00150     @Override
00151     public CFCluster getCF(){
00152         CFCluster cf = copy();
00153         double w = getWeight();
00154         cf.setN(w);
00155         return cf;
00156     }
00157 }
 All Classes Namespaces Files Functions Variables Enumerations