MOA 12.03
Real Time Analytics for Data Streams
|
00001 /* 00002 * GaussianEstimator.java 00003 * Copyright (C) 2007 University of Waikato, Hamilton, New Zealand 00004 * @author Richard Kirkby ([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 package moa.core; 00021 00022 import moa.AbstractMOAObject; 00023 00031 public class GaussianEstimator extends AbstractMOAObject { 00032 00033 private static final long serialVersionUID = 1L; 00034 00035 protected double weightSum; 00036 00037 protected double mean; 00038 00039 protected double varianceSum; 00040 00041 public static final double NORMAL_CONSTANT = Math.sqrt(2 * Math.PI); 00042 00043 public void addObservation(double value, double weight) { 00044 if (Double.isInfinite(value) || Double.isNaN(value)) { 00045 return; 00046 } 00047 if (this.weightSum > 0.0) { 00048 this.weightSum += weight; 00049 double lastMean = this.mean; 00050 this.mean += (value - lastMean) / this.weightSum; 00051 this.varianceSum += (value - lastMean) * (value - this.mean); 00052 } else { 00053 this.mean = value; 00054 this.weightSum = weight; 00055 } 00056 } 00057 00058 public void addObservations(GaussianEstimator obs) { 00059 if ((this.weightSum > 0.0) && (obs.weightSum > 0.0)) { 00060 this.mean = (this.mean * (this.weightSum / (this.weightSum + obs.weightSum))) 00061 + (obs.mean * (obs.weightSum / (this.weightSum + obs.weightSum))); 00062 this.weightSum += obs.weightSum; 00063 this.varianceSum += obs.varianceSum; 00064 } 00065 } 00066 00067 public double getTotalWeightObserved() { 00068 return this.weightSum; 00069 } 00070 00071 public double getMean() { 00072 return this.mean; 00073 } 00074 00075 public double getStdDev() { 00076 return Math.sqrt(getVariance()); 00077 } 00078 00079 public double getVariance() { 00080 return this.weightSum > 1.0 ? this.varianceSum / (this.weightSum - 1.0) 00081 : 0.0; 00082 } 00083 00084 public double probabilityDensity(double value) { 00085 if (this.weightSum > 0.0) { 00086 double stdDev = getStdDev(); 00087 if (stdDev > 0.0) { 00088 double diff = value - getMean(); 00089 return (1.0 / (NORMAL_CONSTANT * stdDev)) 00090 * Math.exp(-(diff * diff / (2.0 * stdDev * stdDev))); 00091 } 00092 return value == getMean() ? 1.0 : 0.0; 00093 } 00094 return 0.0; 00095 } 00096 00097 public double[] estimatedWeight_LessThan_EqualTo_GreaterThan_Value( 00098 double value) { 00099 double equalToWeight = probabilityDensity(value) * this.weightSum; 00100 double stdDev = getStdDev(); 00101 double lessThanWeight = stdDev > 0.0 ? weka.core.Statistics.normalProbability((value - getMean()) / stdDev) 00102 * this.weightSum - equalToWeight 00103 : (value < getMean() ? this.weightSum - equalToWeight : 0.0); 00104 double greaterThanWeight = this.weightSum - equalToWeight 00105 - lessThanWeight; 00106 if (greaterThanWeight < 0.0) { 00107 greaterThanWeight = 0.0; 00108 } 00109 return new double[]{lessThanWeight, equalToWeight, greaterThanWeight}; 00110 } 00111 00112 @Override 00113 public void getDescription(StringBuilder sb, int indent) { 00114 // TODO Auto-generated method stub 00115 } 00116 }