source: src/main/java/weka/classifiers/rules/ZeroR.java @ 16

Last change on this file since 16 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 7.5 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    ZeroR.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.classifiers.rules;
24
25import weka.classifiers.Classifier;
26import weka.classifiers.AbstractClassifier;
27import weka.classifiers.Sourcable;
28import weka.core.Attribute;
29import weka.core.Capabilities;
30import weka.core.Instance;
31import weka.core.Instances;
32import weka.core.RevisionUtils;
33import weka.core.Utils;
34import weka.core.WeightedInstancesHandler;
35import weka.core.Capabilities.Capability;
36
37import java.util.Enumeration;
38
39/**
40 <!-- globalinfo-start -->
41 * Class for building and using a 0-R classifier. Predicts the mean (for a numeric class) or the mode (for a nominal class).
42 * <p/>
43 <!-- globalinfo-end -->
44 *
45 <!-- options-start -->
46 * Valid options are: <p/>
47 *
48 * <pre> -D
49 *  If set, classifier is run in debug mode and
50 *  may output additional info to the console</pre>
51 *
52 <!-- options-end -->
53 *
54 * @author Eibe Frank (eibe@cs.waikato.ac.nz)
55 * @version $Revision: 5928 $
56 */
57public class ZeroR 
58  extends AbstractClassifier
59  implements WeightedInstancesHandler, Sourcable {
60
61  /** for serialization */
62  static final long serialVersionUID = 48055541465867954L;
63 
64  /** The class value 0R predicts. */
65  private double m_ClassValue;
66
67  /** The number of instances in each class (null if class numeric). */
68  private double [] m_Counts;
69 
70  /** The class attribute. */
71  private Attribute m_Class;
72   
73  /**
74   * Returns a string describing classifier
75   * @return a description suitable for
76   * displaying in the explorer/experimenter gui
77   */
78  public String globalInfo() {
79    return "Class for building and using a 0-R classifier. Predicts the mean " 
80      + "(for a numeric class) or the mode (for a nominal class).";         
81  }
82
83  /**
84   * Returns default capabilities of the classifier.
85   *
86   * @return      the capabilities of this classifier
87   */
88  public Capabilities getCapabilities() {
89    Capabilities result = super.getCapabilities();
90    result.disableAll();
91
92    // attributes
93    result.enable(Capability.NOMINAL_ATTRIBUTES);
94    result.enable(Capability.NUMERIC_ATTRIBUTES);
95    result.enable(Capability.DATE_ATTRIBUTES);
96    result.enable(Capability.STRING_ATTRIBUTES);
97    result.enable(Capability.RELATIONAL_ATTRIBUTES);
98    result.enable(Capability.MISSING_VALUES);
99
100    // class
101    result.enable(Capability.NOMINAL_CLASS);
102    result.enable(Capability.NUMERIC_CLASS);
103    result.enable(Capability.DATE_CLASS);
104    result.enable(Capability.MISSING_CLASS_VALUES);
105
106    // instances
107    result.setMinimumNumberInstances(0);
108   
109    return result;
110  }
111
112  /**
113   * Generates the classifier.
114   *
115   * @param instances set of instances serving as training data
116   * @throws Exception if the classifier has not been generated successfully
117   */
118  public void buildClassifier(Instances instances) throws Exception {
119    // can classifier handle the data?
120    getCapabilities().testWithFail(instances);
121
122    // remove instances with missing class
123    instances = new Instances(instances);
124    instances.deleteWithMissingClass();
125   
126    double sumOfWeights = 0;
127
128    m_Class = instances.classAttribute();
129    m_ClassValue = 0;
130    switch (instances.classAttribute().type()) {
131      case Attribute.NUMERIC:
132        m_Counts = null;
133        break;
134      case Attribute.NOMINAL:
135        m_Counts = new double [instances.numClasses()];
136        for (int i = 0; i < m_Counts.length; i++) {
137          m_Counts[i] = 1;
138        }
139        sumOfWeights = instances.numClasses();
140        break;
141    }
142    Enumeration enu = instances.enumerateInstances();
143    while (enu.hasMoreElements()) {
144      Instance instance = (Instance) enu.nextElement();
145      if (!instance.classIsMissing()) {
146        if (instances.classAttribute().isNominal()) {
147          m_Counts[(int)instance.classValue()] += instance.weight();
148        } else {
149          m_ClassValue += instance.weight() * instance.classValue();
150        }
151        sumOfWeights += instance.weight();
152      }
153    }
154    if (instances.classAttribute().isNumeric()) {
155      if (Utils.gr(sumOfWeights, 0)) {
156        m_ClassValue /= sumOfWeights;
157      }
158    } else {
159      m_ClassValue = Utils.maxIndex(m_Counts);
160      Utils.normalize(m_Counts, sumOfWeights);
161    }
162  }
163
164  /**
165   * Classifies a given instance.
166   *
167   * @param instance the instance to be classified
168   * @return index of the predicted class
169   */
170  public double classifyInstance(Instance instance) {
171
172    return m_ClassValue;
173  }
174
175  /**
176   * Calculates the class membership probabilities for the given test instance.
177   *
178   * @param instance the instance to be classified
179   * @return predicted class probability distribution
180   * @throws Exception if class is numeric
181   */
182  public double [] distributionForInstance(Instance instance) 
183       throws Exception {
184         
185    if (m_Counts == null) {
186      double[] result = new double[1];
187      result[0] = m_ClassValue;
188      return result;
189    } else {
190      return (double []) m_Counts.clone();
191    }
192  }
193
194  /**
195   * Returns a string that describes the classifier as source. The
196   * classifier will be contained in a class with the given name (there may
197   * be auxiliary classes),
198   * and will contain a method with the signature:
199   * <pre><code>
200   * public static double classify(Object[] i);
201   * </code></pre>
202   * where the array <code>i</code> contains elements that are either
203   * Double, String, with missing values represented as null. The generated
204   * code is public domain and comes with no warranty.
205   *
206   * @param className the name that should be given to the source class.
207   * @return the object source described by a string
208   * @throws Exception if the souce can't be computed
209   */
210  public String toSource(String className) throws Exception {
211    StringBuffer        result;
212   
213    result = new StringBuffer();
214   
215    result.append("class " + className + " {\n");
216    result.append("  public static double classify(Object[] i) {\n");
217    if (m_Counts != null)
218      result.append("    // always predicts label '" + m_Class.value((int) m_ClassValue) + "'\n");
219    result.append("    return " + m_ClassValue + ";\n");
220    result.append("  }\n");
221    result.append("}\n");
222   
223    return result.toString();
224  }
225 
226  /**
227   * Returns a description of the classifier.
228   *
229   * @return a description of the classifier as a string.
230   */
231  public String toString() {
232
233    if (m_Class ==  null) {
234      return "ZeroR: No model built yet.";
235    }
236    if (m_Counts == null) {
237      return "ZeroR predicts class value: " + m_ClassValue;
238    } else {
239      return "ZeroR predicts class value: " + m_Class.value((int) m_ClassValue);
240    }
241  }
242 
243  /**
244   * Returns the revision string.
245   *
246   * @return            the revision
247   */
248  public String getRevision() {
249    return RevisionUtils.extract("$Revision: 5928 $");
250  }
251
252  /**
253   * Main method for testing this class.
254   *
255   * @param argv the options
256   */
257  public static void main(String [] argv) {
258    runClassifier(new ZeroR(), argv);
259  }
260}
Note: See TracBrowser for help on using the repository browser.