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