source: src/main/java/weka/classifiers/AbstractClassifier.java @ 24

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

Import di weka.

File size: 9.2 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 *    AbstractClassifier.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.classifiers;
24
25import weka.core.Attribute;
26import weka.core.Capabilities;
27import weka.core.CapabilitiesHandler;
28import weka.core.Instance;
29import weka.core.Instances;
30import weka.core.Option;
31import weka.core.OptionHandler;
32import weka.core.RevisionHandler;
33import weka.core.RevisionUtils;
34import weka.core.SerializedObject;
35import weka.core.Utils;
36
37import java.io.Serializable;
38import java.util.Enumeration;
39import java.util.Vector;
40
41/**
42 * Abstract classifier. All schemes for numeric or nominal prediction in
43 * Weka extend this class. Note that a classifier MUST either implement
44 * distributionForInstance() or classifyInstance().
45 *
46 * @author Eibe Frank (eibe@cs.waikato.ac.nz)
47 * @author Len Trigg (trigg@cs.waikato.ac.nz)
48 * @version $Revision: 6041 $
49 */
50public abstract class AbstractClassifier
51  implements Classifier, Cloneable, Serializable, OptionHandler,
52             CapabilitiesHandler, RevisionHandler {
53
54  /** for serialization */
55  private static final long serialVersionUID = 6502780192411755341L;
56
57  /** Whether the classifier is run in debug mode. */
58  protected boolean m_Debug = false;
59
60  /**
61   * Classifies the given test instance. The instance has to belong to a
62   * dataset when it's being classified. Note that a classifier MUST
63   * implement either this or distributionForInstance().
64   *
65   * @param instance the instance to be classified
66   * @return the predicted most likely class for the instance or
67   * Utils.missingValue() if no prediction is made
68   * @exception Exception if an error occurred during the prediction
69   */
70  public double classifyInstance(Instance instance) throws Exception {
71
72    double [] dist = distributionForInstance(instance);
73    if (dist == null) {
74      throw new Exception("Null distribution predicted");
75    }
76    switch (instance.classAttribute().type()) {
77    case Attribute.NOMINAL:
78      double max = 0;
79      int maxIndex = 0;
80
81      for (int i = 0; i < dist.length; i++) {
82        if (dist[i] > max) {
83          maxIndex = i;
84          max = dist[i];
85        }
86      }
87      if (max > 0) {
88        return maxIndex;
89      } else {
90        return Utils.missingValue();
91      }
92    case Attribute.NUMERIC:
93      return dist[0];
94    default:
95      return Utils.missingValue();
96    }
97  }
98
99  /**
100   * Predicts the class memberships for a given instance. If
101   * an instance is unclassified, the returned array elements
102   * must be all zero. If the class is numeric, the array
103   * must consist of only one element, which contains the
104   * predicted value. Note that a classifier MUST implement
105   * either this or classifyInstance().
106   *
107   * @param instance the instance to be classified
108   * @return an array containing the estimated membership
109   * probabilities of the test instance in each class
110   * or the numeric prediction
111   * @exception Exception if distribution could not be
112   * computed successfully
113   */
114  public double[] distributionForInstance(Instance instance) throws Exception {
115
116    double[] dist = new double[instance.numClasses()];
117    switch (instance.classAttribute().type()) {
118      case Attribute.NOMINAL:
119        double classification = classifyInstance(instance);
120        if (Utils.isMissingValue(classification)) {
121          return dist;
122        } else {
123          dist[(int)classification] = 1.0;
124        }
125        return dist;
126      case Attribute.NUMERIC:
127        dist[0] = classifyInstance(instance);
128        return dist;
129      default:
130        return dist;
131    }
132  }
133
134  /**
135   * Creates a new instance of a classifier given it's class name and
136   * (optional) arguments to pass to it's setOptions method. If the
137   * classifier implements OptionHandler and the options parameter is
138   * non-null, the classifier will have it's options set.
139   *
140   * @param classifierName the fully qualified class name of the classifier
141   * @param options an array of options suitable for passing to setOptions. May
142   * be null.
143   * @return the newly created classifier, ready for use.
144   * @exception Exception if the classifier name is invalid, or the options
145   * supplied are not acceptable to the classifier
146   */
147  public static Classifier forName(String classifierName,
148      String [] options) throws Exception {
149
150    return ((AbstractClassifier)Utils.forName(Classifier.class,
151                                              classifierName,
152                                              options));
153  }
154
155  /**
156   * Creates a deep copy of the given classifier using serialization.
157   *
158   * @param model the classifier to copy
159   * @return a deep copy of the classifier
160   * @exception Exception if an error occurs
161   */
162  public static Classifier makeCopy(Classifier model) throws Exception {
163
164    return (Classifier)new SerializedObject(model).getObject();
165  }
166
167  /**
168   * Creates a given number of deep copies of the given classifier using serialization.
169   *
170   * @param model the classifier to copy
171   * @param num the number of classifier copies to create.
172   * @return an array of classifiers.
173   * @exception Exception if an error occurs
174   */
175  public static Classifier [] makeCopies(Classifier model, int num) throws Exception {
176
177    if (model == null) {
178      throw new Exception("No model classifier set");
179    }
180    Classifier [] classifiers = new Classifier [num];
181    SerializedObject so = new SerializedObject(model);
182    for(int i = 0; i < classifiers.length; i++) {
183      classifiers[i] = (Classifier) so.getObject();
184    }
185    return classifiers;
186  }
187
188  /**
189   * Returns an enumeration describing the available options.
190   *
191   * @return an enumeration of all the available options.
192   */
193  public Enumeration listOptions() {
194
195    Vector newVector = new Vector(1);
196
197    newVector.addElement(new Option(
198          "\tIf set, classifier is run in debug mode and\n"
199          + "\tmay output additional info to the console",
200          "D", 0, "-D"));
201    return newVector.elements();
202  }
203
204  /**
205   * Parses a given list of options. Valid options are:<p>
206   *
207   * -D  <br>
208   * If set, classifier is run in debug mode and
209   * may output additional info to the console.<p>
210   *
211   * @param options the list of options as an array of strings
212   * @exception Exception if an option is not supported
213   */
214  public void setOptions(String[] options) throws Exception {
215
216    setDebug(Utils.getFlag('D', options));
217  }
218
219  /**
220   * Gets the current settings of the Classifier.
221   *
222   * @return an array of strings suitable for passing to setOptions
223   */
224  public String [] getOptions() {
225
226    String [] options;
227    if (getDebug()) {
228      options = new String[1];
229      options[0] = "-D";
230    } else {
231      options = new String[0];
232    }
233    return options;
234  }
235
236  /**
237   * Set debugging mode.
238   *
239   * @param debug true if debug output should be printed
240   */
241  public void setDebug(boolean debug) {
242
243    m_Debug = debug;
244  }
245
246  /**
247   * Get whether debugging is turned on.
248   *
249   * @return true if debugging output is on
250   */
251  public boolean getDebug() {
252
253    return m_Debug;
254  }
255
256  /**
257   * Returns the tip text for this property
258   * @return tip text for this property suitable for
259   * displaying in the explorer/experimenter gui
260   */
261  public String debugTipText() {
262    return "If set to true, classifier may output additional info to " +
263      "the console.";
264  }
265
266  /**
267   * Returns the Capabilities of this classifier. Maximally permissive
268   * capabilities are allowed by default. Derived classifiers should
269   * override this method and first disable all capabilities and then
270   * enable just those capabilities that make sense for the scheme.
271   *
272   * @return            the capabilities of this object
273   * @see               Capabilities
274   */
275  public Capabilities getCapabilities() {
276    Capabilities result = new Capabilities(this);
277    result.enableAll();
278
279    return result;
280  }
281
282  /**
283   * Returns the revision string.
284   *
285   * @return            the revision
286   */
287  public String getRevision() {
288    return RevisionUtils.extract("$Revision: 6041 $");
289  }
290
291  /**
292   * runs the classifier instance with the given options.
293   *
294   * @param classifier          the classifier to run
295   * @param options     the commandline options
296   */
297  protected static void runClassifier(Classifier classifier, String[] options) {
298    try {
299      System.out.println(Evaluation.evaluateModel(classifier, options));
300    }
301    catch (Exception e) {
302      if (    ((e.getMessage() != null) && (e.getMessage().indexOf("General options") == -1))
303          || (e.getMessage() == null) )
304        e.printStackTrace();
305      else
306        System.err.println(e.getMessage());
307    }
308  }
309}
310
Note: See TracBrowser for help on using the repository browser.