C45PruneableDecList.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 5k
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.  *    C45PruneableDecList.java
  18.  *    Copyright (C) 1999 Eibe Frank
  19.  *
  20.  */
  21. package weka.classifiers.j48;
  22. import weka.core.*;
  23. /**
  24.  * Class for handling a partial tree structure pruned using C4.5's
  25.  * pruning heuristic.
  26.  *
  27.  * @author Eibe Frank (eibe@cs.waikato.ac.nz)
  28.  * @version $Revision: 1.4 $
  29.  */
  30. public class C45PruneableDecList extends ClassifierDecList{
  31.     
  32.   /** CF */
  33.   private double CF = 0.25;
  34.   /** Minimum number of objects */
  35.   private int minNumObj;
  36.   /** To compute the entropy. */
  37.   private static EntropySplitCrit splitCrit = new EntropySplitCrit();
  38.   
  39.   /**
  40.    * Constructor for pruneable tree structure. Stores reference
  41.    * to associated training data at each node.
  42.    *
  43.    * @param toSelectLocModel selection method for local splitting model
  44.    * @param cf the confidence factor for pruning
  45.    * @param minNum the minimum number of objects in a leaf
  46.    * @exception Exception if something goes wrong
  47.    */
  48.   public C45PruneableDecList(ModelSelection toSelectLocModel, 
  49.      double cf, int minNum) 
  50.        throws Exception {
  51.        
  52.     super(toSelectLocModel);
  53.     
  54.     CF = cf;
  55.     minNumObj = minNum;
  56.   }
  57.   
  58.   /**
  59.    * Method for building a pruned partial tree.
  60.    *
  61.    * @exception Exception if something goes wrong
  62.    */
  63.   public void buildRule(Instances data) throws Exception {
  64.     
  65.     buildDecList(data, false);
  66.     cleanup(new Instances(data, 0));
  67.   }
  68.   
  69.   /**
  70.    * Method for choosing a subset to expand.
  71.    */
  72.   public final int chooseIndex() {
  73.     
  74.     int minIndex = -1;
  75.     double estimated, min = Double.MAX_VALUE;
  76.     int i, j;
  77.     for (i = 0; i < m_sons.length; i++)
  78.       if (son(i) == null) {
  79. if (Utils.sm(localModel().distribution().perBag(i),
  80.      (double)minNumObj))
  81.   estimated = Double.MAX_VALUE;
  82. else{
  83.   estimated = 0;
  84.   for (j = 0; j < localModel().distribution().numClasses(); j++) 
  85.     estimated -= splitCrit.logFunc(localModel().distribution().
  86.      perClassPerBag(i,j));
  87.   estimated += splitCrit.logFunc(localModel().distribution().
  88.    perBag(i));
  89.   estimated /= localModel().distribution().perBag(i);
  90. }
  91. if (Utils.smOrEq(estimated,0))
  92.   return i;
  93. if (Utils.sm(estimated,min)) {
  94.   min = estimated;
  95.   minIndex = i;
  96. }
  97.       }
  98.     return minIndex;
  99.   }
  100.   
  101.   /**
  102.    * Choose last index (ie. choose rule).
  103.    */
  104.   public final int chooseLastIndex() {
  105.     
  106.     int minIndex = 0;
  107.     double estimated, min = Double.MAX_VALUE;
  108.     
  109.     if (!m_isLeaf) 
  110.       for (int i = 0; i < m_sons.length; i++)
  111. if (son(i) != null) {
  112.   if (Utils.grOrEq(localModel().distribution().perBag(i),
  113.    (double)minNumObj)) {
  114.     estimated = son(i).getSizeOfBranch();
  115.     if (Utils.sm(estimated,min)) {
  116.       min = estimated;
  117.       minIndex = i;
  118.     }
  119.   }
  120. }
  121.     return minIndex;
  122.   }
  123.   
  124.   /**
  125.    * Returns a newly created tree.
  126.    *
  127.    * @exception Exception if something goes wrong
  128.    */
  129.   protected ClassifierDecList getNewDecList(Instances data, boolean leaf) 
  130.        throws Exception {
  131.  
  132.     C45PruneableDecList newDecList = 
  133.       new C45PruneableDecList(m_toSelectModel,CF, minNumObj);
  134.     
  135.     newDecList.buildDecList((Instances)data, leaf);
  136.     
  137.     return newDecList;
  138.   }
  139.   /**
  140.    * Prunes the end of the rule.
  141.    */
  142.   protected void pruneEnd() {
  143.     
  144.     double errorsLeaf, errorsTree;
  145.     
  146.     errorsTree = getEstimatedErrorsForTree();
  147.     errorsLeaf = getEstimatedErrorsForLeaf();
  148.     if (Utils.smOrEq(errorsLeaf,errorsTree+0.1)) { // +0.1 as in C4.5
  149.       m_isLeaf = true;
  150.       m_sons = null;
  151.       m_localModel = new NoSplit(localModel().distribution());
  152.     }
  153.   }
  154.   
  155.   /**
  156.    * Computes estimated errors for tree.
  157.    */
  158.   private double getEstimatedErrorsForTree() {
  159.     if (m_isLeaf)
  160.       return getEstimatedErrorsForLeaf();
  161.     else {
  162.       double error = 0;
  163.       for (int i = 0; i < m_sons.length; i++) 
  164. if (!Utils.eq(son(i).localModel().distribution().total(),0))
  165.   error += son(i).getEstimatedErrorsForTree();
  166.       return error;
  167.     }
  168.   }
  169.   
  170.   /**
  171.    * Computes estimated errors for leaf.
  172.    */
  173.   public double getEstimatedErrorsForLeaf() {
  174.   
  175.     double errors = localModel().distribution().numIncorrect();
  176.     return errors+Stats.addErrs(localModel().distribution().total(),
  177. errors,(float)CF);
  178.   }
  179.  
  180.   /**
  181.    * Returns the number of instances covered by a branch
  182.    */
  183.   private double getSizeOfBranch() {
  184.     
  185.     if (m_isLeaf) {
  186.       return -localModel().distribution().total();
  187.     } else
  188.       return son(indeX).getSizeOfBranch();
  189.   }
  190.   /**
  191.    * Method just exists to make program easier to read.
  192.    */
  193.   private ClassifierSplitModel localModel() {
  194.     
  195.     return (ClassifierSplitModel)m_localModel;
  196.   }
  197.   
  198.   /**
  199.    * Method just exists to make program easier to read.
  200.    */
  201.   private C45PruneableDecList son(int index) {
  202.     
  203.     return (C45PruneableDecList)m_sons[index];
  204.   }
  205. }