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