ClassifierSplitModel.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 7k
Category:

Windows Develop

Development Platform:

Java

  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.  *    ClassifierSplitModel.java
  18.  *    Copyright (C) 1999 Eibe Frank
  19.  *
  20.  */
  21. package weka.classifiers.j48;
  22. import java.io.*;
  23. import java.util.*;
  24. import weka.core.*;
  25. /** 
  26.  * Abstract class for classification models that can be used 
  27.  * recursively to split the data.
  28.  *
  29.  * @author Eibe Frank (eibe@cs.waikato.ac.nz)
  30.  * @version $Revision: 1.6 $
  31.  */
  32. public abstract class ClassifierSplitModel implements Cloneable, Serializable {
  33.   /** Distribution of class values. */  
  34.   protected Distribution m_distribution;  
  35.   /** Number of created subsets. */
  36.   protected int m_numSubsets;         
  37.   /**
  38.    * Allows to clone a model (shallow copy).
  39.    */
  40.   public Object clone() {
  41.     Object clone = null;
  42.     
  43.     try {
  44.       clone = super.clone();
  45.     } catch (CloneNotSupportedException e) {
  46.     } 
  47.     return clone;
  48.   }
  49.   /**
  50.    * Builds the classifier split model for the given set of instances.
  51.    *
  52.    * @exception Exception if something goes wrong
  53.    */
  54.   abstract public void buildClassifier(Instances instances) throws Exception;
  55.   
  56.   /**
  57.    * Checks if generated model is valid.
  58.    */
  59.   public final boolean checkModel() {
  60.     
  61.     if (m_numSubsets > 0)
  62.       return true;
  63.     else
  64.       return false;
  65.   }
  66.   
  67.   /**
  68.    * Classifies a given instance.
  69.    *
  70.    * @exception Exception if something goes wrong
  71.    */
  72.   public final double classifyInstance(Instance instance)
  73.        throws Exception {
  74.     
  75.     int theSubset;
  76.     
  77.     theSubset = whichSubset(instance);
  78.     if (theSubset > -1)
  79.       return (double)m_distribution.maxClass(theSubset);
  80.     else
  81.       return (double)m_distribution.maxClass();
  82.   }
  83.   /**
  84.    * Gets class probability for instance.
  85.    *
  86.    * @exception Exception if something goes wrong
  87.    */
  88.   public double classProb(int classIndex, Instance instance, int theSubset) 
  89.        throws Exception {
  90.     if (theSubset > -1) {
  91.       return m_distribution.prob(classIndex,theSubset);
  92.     } else {
  93.       double [] weights = weights(instance);
  94.       if (weights == null) {
  95. return m_distribution.prob(classIndex);
  96.       } else {
  97. double prob = 0;
  98. for (int i = 0; i < weights.length; i++) {
  99.   prob += weights[i] * m_distribution.prob(classIndex, i);
  100. }
  101. return prob;
  102.       }
  103.     }
  104.   }
  105.   /**
  106.    * Gets class probability for instance.
  107.    *
  108.    * @exception Exception if something goes wrong
  109.    */
  110.   public double classProbLaplace(int classIndex, Instance instance,
  111.  int theSubset) throws Exception {
  112.     if (theSubset > -1) {
  113.       return m_distribution.laplaceProb(classIndex, theSubset);
  114.     } else {
  115.       double [] weights = weights(instance);
  116.       if (weights == null) {
  117. return m_distribution.laplaceProb(classIndex);
  118.       } else {
  119. double prob = 0;
  120. for (int i = 0; i < weights.length; i++) {
  121.   prob += weights[i] * m_distribution.laplaceProb(classIndex, i);
  122. }
  123. return prob;
  124.       }
  125.     }
  126.   }
  127.   /**
  128.    * Returns coding costs of model. Returns 0 if not overwritten.
  129.    */
  130.   public double codingCost() {
  131.     return 0;
  132.   }
  133.   /**
  134.    * Returns the distribution of class values induced by the model.
  135.    */
  136.   public final Distribution distribution() {
  137.     return m_distribution;
  138.   }
  139.   /**
  140.    * Prints left side of condition satisfied by instances.
  141.    *
  142.    * @param data the data.
  143.    */
  144.   abstract public String leftSide(Instances data);
  145.   /**
  146.    * Prints left side of condition satisfied by instances in subset index.
  147.    */
  148.   abstract public String rightSide(int index,Instances data);
  149.   /**
  150.    * Prints label for subset index of instances (eg class).
  151.    *
  152.    * @exception Exception if something goes wrong
  153.    */
  154.   public final String dumpLabel(int index,Instances data) throws Exception {
  155.     StringBuffer text;
  156.     text = new StringBuffer();
  157.     text.append(((Instances)data).classAttribute().
  158. value(m_distribution.maxClass(index)));
  159.     text.append(" ("+Utils.roundDouble(m_distribution.perBag(index),2));
  160.     if (Utils.gr(m_distribution.numIncorrect(index),0))
  161.       text.append("/"+Utils.roundDouble(m_distribution.numIncorrect(index),2));
  162.     text.append(")");
  163.     return text.toString();
  164.   }
  165.   
  166.   public final String sourceClass(int index, Instances data) throws Exception {
  167.     System.err.println("sourceClass");
  168.     return (new StringBuffer(m_distribution.maxClass(index))).toString();
  169.   }
  170.   public abstract String sourceExpression(int index, Instances data);
  171.   /**
  172.    * Prints the split model.
  173.    *
  174.    * @exception Exception if something goes wrong
  175.    */
  176.   public final String dumpModel(Instances data) throws Exception {
  177.     StringBuffer text;
  178.     int i;
  179.     text = new StringBuffer();
  180.     for (i=0;i<m_numSubsets;i++) {
  181.       text.append(leftSide(data)+rightSide(i,data)+": ");
  182.       text.append(dumpLabel(i,data)+"n");
  183.     }
  184.     return text.toString();
  185.   }
  186.  
  187.   /**
  188.    * Returns the number of created subsets for the split.
  189.    */
  190.   public final int numSubsets() {
  191.     return m_numSubsets;
  192.   }
  193.   
  194.   /**
  195.    * Sets distribution associated with model.
  196.    */
  197.   public void resetDistribution(Instances data) throws Exception {
  198.     m_distribution = new Distribution(data, this);
  199.   }
  200.   /**
  201.    * Splits the given set of instances into subsets.
  202.    *
  203.    * @exception Exception if something goes wrong
  204.    */
  205.   public final Instances [] split(Instances data) 
  206.        throws Exception { 
  207.     Instances [] instances = new Instances [m_numSubsets];
  208.     double [] weights;
  209.     double newWeight;
  210.     Instance instance;
  211.     int subset, i, j;
  212.     for (j=0;j<m_numSubsets;j++)
  213.       instances[j] = new Instances((Instances)data,
  214.     data.numInstances());
  215.     for (i = 0; i < data.numInstances(); i++) {
  216.       instance = ((Instances) data).instance(i);
  217.       weights = weights(instance);
  218.       subset = whichSubset(instance);
  219.       if (subset > -1)
  220. instances[subset].add(instance);
  221.       else
  222. for (j = 0; j < m_numSubsets; j++)
  223.   if (Utils.gr(weights[j],0)) {
  224.     newWeight = weights[j]*instance.weight();
  225.     instances[j].add(instance);
  226.     instances[j].lastInstance().setWeight(newWeight);
  227.   }
  228.     }
  229.     for (j = 0; j < m_numSubsets; j++)
  230.       instances[j].compactify();
  231.     
  232.     return instances;
  233.   }
  234.   /**
  235.    * Returns weights if instance is assigned to more than one subset.
  236.    * Returns null if instance is only assigned to one subset.
  237.    */
  238.   abstract public double [] weights(Instance instance);
  239.   
  240.   /**
  241.    * Returns index of subset instance is assigned to.
  242.    * Returns -1 if instance is assigned to more than one subset.
  243.    *
  244.    * @exception Exception if something goes wrong
  245.    */
  246.   abstract public int whichSubset(Instance instance) throws Exception;
  247. }