001: /*
002: * This program is free software; you can redistribute it and/or modify
003: * it under the terms of the GNU General Public License as published by
004: * the Free Software Foundation; either version 2 of the License, or
005: * (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: /*
018: * PoissonEstimator.java
019: * Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
020: *
021: */
022:
023: package weka.estimators;
024:
025: import weka.core.Capabilities.Capability;
026: import weka.core.Capabilities;
027: import weka.core.Utils;
028:
029: /**
030: * Simple probability estimator that places a single Poisson distribution
031: * over the observed values.
032: *
033: * @author Len Trigg (trigg@cs.waikato.ac.nz)
034: * @version $Revision: 1.7 $
035: */
036: public class PoissonEstimator extends Estimator implements
037: IncrementalEstimator {
038:
039: /** for serialization */
040: private static final long serialVersionUID = 7669362595289236662L;
041:
042: /** The number of values seen */
043: private double m_NumValues;
044:
045: /** The sum of the values seen */
046: private double m_SumOfValues;
047:
048: /**
049: * The average number of times
050: * an event occurs in an interval.
051: */
052: private double m_Lambda;
053:
054: /**
055: * Calculates the log factorial of a number.
056: *
057: * @param x input number.
058: * @return log factorial of x.
059: */
060: private double logFac(double x) {
061:
062: double result = 0;
063: for (double i = 2; i <= x; i++) {
064: result += Math.log(i);
065: }
066: return result;
067: }
068:
069: /**
070: * Returns value for Poisson distribution
071: *
072: * @param x the argument to the kernel function
073: * @return the value for a Poisson kernel
074: */
075: private double Poisson(double x) {
076:
077: return Math.exp(-m_Lambda + (x * Math.log(m_Lambda))
078: - logFac(x));
079: }
080:
081: /**
082: * Add a new data value to the current estimator.
083: *
084: * @param data the new data value
085: * @param weight the weight assigned to the data value
086: */
087: public void addValue(double data, double weight) {
088:
089: m_NumValues += weight;
090: m_SumOfValues += data * weight;
091: if (m_NumValues != 0) {
092: m_Lambda = m_SumOfValues / m_NumValues;
093: }
094: }
095:
096: /**
097: * Get a probability estimate for a value
098: *
099: * @param data the value to estimate the probability of
100: * @return the estimated probability of the supplied value
101: */
102: public double getProbability(double data) {
103:
104: return Poisson(data);
105: }
106:
107: /** Display a representation of this estimator */
108: public String toString() {
109:
110: return "Poisson Lambda = "
111: + Utils.doubleToString(m_Lambda, 4, 2) + "\n";
112: }
113:
114: /**
115: * Returns default capabilities of the classifier.
116: *
117: * @return the capabilities of this classifier
118: */
119: public Capabilities getCapabilities() {
120: Capabilities result = super .getCapabilities();
121:
122: // attributes
123: result.enable(Capability.NUMERIC_ATTRIBUTES);
124: return result;
125: }
126:
127: /**
128: * Main method for testing this class.
129: *
130: * @param argv should contain a sequence of numeric values
131: */
132: public static void main(String[] argv) {
133:
134: try {
135: if (argv.length == 0) {
136: System.out
137: .println("Please specify a set of instances.");
138: return;
139: }
140: PoissonEstimator newEst = new PoissonEstimator();
141: for (int i = 0; i < argv.length; i++) {
142: double current = Double.valueOf(argv[i]).doubleValue();
143: System.out.println(newEst);
144: System.out.println("Prediction for " + current + " = "
145: + newEst.getProbability(current));
146: newEst.addValue(current, 1);
147: }
148:
149: } catch (Exception e) {
150: System.out.println(e.getMessage());
151: }
152: }
153: }
|