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: * DNConditionalEstimator.java
019: * Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
020: *
021: */
022:
023: package weka.estimators;
024:
025: /**
026: * Conditional probability estimator for a discrete domain conditional upon
027: * a numeric domain.
028: *
029: * @author Len Trigg (trigg@cs.waikato.ac.nz)
030: * @version $Revision: 1.7 $
031: */
032: public class DNConditionalEstimator implements ConditionalEstimator {
033:
034: /** Hold the sub-estimators */
035: private NormalEstimator[] m_Estimators;
036:
037: /** Hold the weights for each of the sub-estimators */
038: private DiscreteEstimator m_Weights;
039:
040: /**
041: * Constructor
042: *
043: * @param numSymbols the number of symbols
044: * @param precision the precision to which numeric values are given. For
045: * example, if the precision is stated to be 0.1, the values in the
046: * interval (0.25,0.35] are all treated as 0.3.
047: */
048: public DNConditionalEstimator(int numSymbols, double precision) {
049:
050: m_Estimators = new NormalEstimator[numSymbols];
051: for (int i = 0; i < numSymbols; i++) {
052: m_Estimators[i] = new NormalEstimator(precision);
053: }
054: m_Weights = new DiscreteEstimator(numSymbols, true);
055: }
056:
057: /**
058: * Add a new data value to the current estimator.
059: *
060: * @param data the new data value
061: * @param given the new value that data is conditional upon
062: * @param weight the weight assigned to the data value
063: */
064: public void addValue(double data, double given, double weight) {
065:
066: m_Estimators[(int) data].addValue(given, weight);
067: m_Weights.addValue((int) data, weight);
068: }
069:
070: /**
071: * Get a probability estimator for a value
072: *
073: * @param given the new value that data is conditional upon
074: * @return the estimator for the supplied value given the condition
075: */
076: public Estimator getEstimator(double given) {
077:
078: Estimator result = new DiscreteEstimator(m_Estimators.length,
079: false);
080: for (int i = 0; i < m_Estimators.length; i++) {
081: result.addValue(i, m_Weights.getProbability(i)
082: * m_Estimators[i].getProbability(given));
083: }
084: return result;
085: }
086:
087: /**
088: * Get a probability estimate for a value
089: *
090: * @param data the value to estimate the probability of
091: * @param given the new value that data is conditional upon
092: * @return the estimated probability of the supplied value
093: */
094: public double getProbability(double data, double given) {
095:
096: return getEstimator(given).getProbability(data);
097: }
098:
099: /** Display a representation of this estimator */
100: public String toString() {
101:
102: String result = "DN Conditional Estimator. "
103: + m_Estimators.length + " sub-estimators:\n";
104: for (int i = 0; i < m_Estimators.length; i++) {
105: result += "Sub-estimator " + i + ": " + m_Estimators[i];
106: }
107: result += "Weights of each estimator given by " + m_Weights;
108: return result;
109: }
110:
111: /**
112: * Main method for testing this class.
113: *
114: * @param argv should contain a sequence of pairs of integers which
115: * will be treated as pairs of symbolic, numeric.
116: */
117: public static void main(String[] argv) {
118:
119: try {
120: if (argv.length == 0) {
121: System.out
122: .println("Please specify a set of instances.");
123: return;
124: }
125: int currentA = Integer.parseInt(argv[0]);
126: int maxA = currentA;
127: int currentB = Integer.parseInt(argv[1]);
128: int maxB = currentB;
129: for (int i = 2; i < argv.length - 1; i += 2) {
130: currentA = Integer.parseInt(argv[i]);
131: currentB = Integer.parseInt(argv[i + 1]);
132: if (currentA > maxA) {
133: maxA = currentA;
134: }
135: if (currentB > maxB) {
136: maxB = currentB;
137: }
138: }
139: DNConditionalEstimator newEst = new DNConditionalEstimator(
140: maxA + 1, 1);
141: for (int i = 0; i < argv.length - 1; i += 2) {
142: currentA = Integer.parseInt(argv[i]);
143: currentB = Integer.parseInt(argv[i + 1]);
144: System.out.println(newEst);
145: System.out.println("Prediction for " + currentA + '|'
146: + currentB + " = "
147: + newEst.getProbability(currentA, currentB));
148: newEst.addValue(currentA, currentB, 1);
149: }
150: } catch (Exception e) {
151: System.out.println(e.getMessage());
152: }
153: }
154: }
|