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: * DKConditionalEstimator.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 DKConditionalEstimator implements ConditionalEstimator {
033:
034: /** Hold the sub-estimators */
035: private KernelEstimator[] 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 DKConditionalEstimator(int numSymbols, double precision) {
049:
050: m_Estimators = new KernelEstimator[numSymbols];
051: for (int i = 0; i < numSymbols; i++) {
052: m_Estimators[i] = new KernelEstimator(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: //System.out.println("Val " + i
082: // + " Weight:" + m_Weights.getProbability(i)
083: // +" EstProb(" + given + ")="
084: // + m_Estimators[i].getProbability(given));
085: result.addValue(i, m_Weights.getProbability(i)
086: * m_Estimators[i].getProbability(given));
087: }
088: return result;
089: }
090:
091: /**
092: * Get a probability estimate for a value
093: *
094: * @param data the value to estimate the probability of
095: * @param given the new value that data is conditional upon
096: * @return the estimated probability of the supplied value
097: */
098: public double getProbability(double data, double given) {
099:
100: return getEstimator(given).getProbability(data);
101: }
102:
103: /**
104: * Display a representation of this estimator
105: */
106: public String toString() {
107:
108: String result = "DK Conditional Estimator. "
109: + m_Estimators.length + " sub-estimators:\n";
110: for (int i = 0; i < m_Estimators.length; i++) {
111: result += "Sub-estimator " + i + ": " + m_Estimators[i];
112: }
113: result += "Weights of each estimator given by " + m_Weights;
114: return result;
115: }
116:
117: /**
118: * Main method for testing this class.
119: *
120: * @param argv should contain a sequence of pairs of integers which
121: * will be treated as pairs of symbolic, numeric.
122: */
123: public static void main(String[] argv) {
124:
125: try {
126: if (argv.length == 0) {
127: System.out
128: .println("Please specify a set of instances.");
129: return;
130: }
131: int currentA = Integer.parseInt(argv[0]);
132: int maxA = currentA;
133: int currentB = Integer.parseInt(argv[1]);
134: int maxB = currentB;
135: for (int i = 2; i < argv.length - 1; i += 2) {
136: currentA = Integer.parseInt(argv[i]);
137: currentB = Integer.parseInt(argv[i + 1]);
138: if (currentA > maxA) {
139: maxA = currentA;
140: }
141: if (currentB > maxB) {
142: maxB = currentB;
143: }
144: }
145: DKConditionalEstimator newEst = new DKConditionalEstimator(
146: maxA + 1, 1);
147: for (int i = 0; i < argv.length - 1; i += 2) {
148: currentA = Integer.parseInt(argv[i]);
149: currentB = Integer.parseInt(argv[i + 1]);
150: System.out.println(newEst);
151: System.out.println("Prediction for " + currentA + '|'
152: + currentB + " = "
153: + newEst.getProbability(currentA, currentB));
154: newEst.addValue(currentA, currentB, 1);
155: }
156: } catch (Exception e) {
157: System.out.println(e.getMessage());
158: }
159: }
160: }
|