PruneableDecList.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.  *    PruneableDecList.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 that
  25.  * can be pruned using a pruning set.
  26.  *
  27.  * @author Eibe Frank (eibe@cs.waikato.ac.nz)
  28.  * @version $Revision: 1.4 $
  29.  */
  30. public class PruneableDecList extends ClassifierDecList{
  31.   /** Minimum number of objects */
  32.   private int m_MinNumObj;
  33.  
  34.   /** To compute the entropy. */
  35.   private static EntropySplitCrit m_splitCrit = new EntropySplitCrit();
  36.   
  37.   /**
  38.    * Constructor for pruneable partial tree structure. 
  39.    *
  40.    * @param toSelectLocModel selection method for local splitting model
  41.    * @param minNum minimum number of objects in leaf
  42.    */
  43.   public PruneableDecList(ModelSelection toSelectLocModel,
  44.   int minNum) {
  45.        
  46.     super(toSelectLocModel);
  47.     m_MinNumObj = minNum;
  48.   }
  49.   
  50.   /**
  51.    * Method for building a pruned partial tree.
  52.    *
  53.    * @exception Exception if tree can't be built successfully
  54.    */
  55.   public void buildRule(Instances train,
  56. Instances test) throws Exception { 
  57.     
  58.     buildDecList(train, test, false);
  59.     cleanup(new Instances(train, 0));
  60.   }
  61.   
  62.   /**
  63.    * Method for choosing a subset to expand.
  64.    */
  65.   public final int chooseIndex() {
  66.     
  67.     int minIndex = -1;
  68.     double estimated, min = Double.MAX_VALUE;
  69.     int i, j;
  70.     for (i = 0; i < m_sons.length; i++)
  71.       if (son(i) == null){
  72. if (Utils.sm(localModel().distribution().perBag(i),
  73.      (double)m_MinNumObj))
  74.   estimated = Double.MAX_VALUE;
  75. else{
  76.   estimated = 0;
  77.   for (j = 0; j < localModel().distribution().numClasses(); j++) 
  78.     estimated -= m_splitCrit.logFunc(localModel().distribution().
  79.      perClassPerBag(i,j));
  80.   estimated += m_splitCrit.logFunc(localModel().distribution().
  81.    perBag(i));
  82.   estimated /= localModel().distribution().perBag(i);
  83. }
  84. if (Utils.smOrEq(estimated,0)) // This is certainly a good one.
  85.   return i;
  86. if (Utils.sm(estimated,min)){
  87.   min = estimated;
  88.   minIndex = i;
  89. }
  90.       }
  91.     return minIndex;
  92.   }
  93.   
  94.   /**
  95.    * Choose last index (ie. choose rule).
  96.    */
  97.   public final int chooseLastIndex() {
  98.     
  99.     int minIndex = 0;
  100.     double estimated, min = Double.MAX_VALUE;
  101.     
  102.     if (!m_isLeaf) 
  103.       for (int i = 0; i < m_sons.length; i++)
  104. if (son(i) != null){
  105.   if (Utils.grOrEq(localModel().distribution().perBag(i),
  106.    (double)m_MinNumObj)) {
  107.     estimated = son(i).getSizeOfBranch();
  108.     if (Utils.sm(estimated,min)){
  109.       min = estimated;
  110.       minIndex = i;
  111.     }
  112.   }
  113. }
  114.     return minIndex;
  115.   }
  116.   
  117.   /**
  118.    * Returns a newly created tree.
  119.    *
  120.    * @param data and selection method for local models.
  121.    * @exception Exception if something goes wrong
  122.    */
  123.   protected ClassifierDecList getNewDecList(Instances train, Instances test, 
  124.     boolean leaf) throws Exception {
  125.  
  126.     PruneableDecList newDecList = 
  127.       new PruneableDecList(m_toSelectModel, m_MinNumObj);
  128.     
  129.     newDecList.buildDecList((Instances)train, test, leaf);
  130.     
  131.     return newDecList;
  132.   }
  133.   /**
  134.    * Prunes the end of the rule.
  135.    */
  136.   protected void pruneEnd() throws Exception {
  137.     
  138.     double errorsLeaf, errorsTree;
  139.     
  140.     errorsTree = errorsForTree();
  141.     errorsLeaf = errorsForLeaf();
  142.     if (Utils.smOrEq(errorsLeaf,errorsTree)){ 
  143.       m_isLeaf = true;
  144.       m_sons = null;
  145.       m_localModel = new NoSplit(localModel().distribution());
  146.     }
  147.   }
  148.   /**
  149.    * Computes error estimate for tree.
  150.    */
  151.   private double errorsForTree() throws Exception {
  152.     Distribution test;
  153.     if (m_isLeaf)
  154.       return errorsForLeaf();
  155.     else {
  156.       double error = 0;
  157.       for (int i = 0; i < m_sons.length; i++) 
  158. if (Utils.eq(son(i).localModel().distribution().total(),0)) {
  159.   error += m_test.perBag(i)-
  160.     m_test.perClassPerBag(i,localModel().distribution().
  161. maxClass());
  162. } else
  163.   error += son(i).errorsForTree();
  164.       return error;
  165.     }
  166.   }
  167.   /**
  168.    * Computes estimated errors for leaf.
  169.    */
  170.   private double errorsForLeaf() throws Exception {
  171.     return m_test.total()-
  172.     m_test.perClass(localModel().distribution().maxClass());
  173.   }
  174.  
  175.   /**
  176.    * Returns the number of instances covered by a branch
  177.    */
  178.   private double getSizeOfBranch() {
  179.     
  180.     if (m_isLeaf) {
  181.       return -localModel().distribution().total();
  182.     } else
  183.       return son(indeX).getSizeOfBranch();
  184.   }
  185.   /**
  186.    * Method just exists to make program easier to read.
  187.    */
  188.   private ClassifierSplitModel localModel() {
  189.     
  190.     return (ClassifierSplitModel)m_localModel;
  191.   }
  192.   
  193.   /**
  194.    * Method just exists to make program easier to read.
  195.    */
  196.   private PruneableDecList son(int index) {
  197.     
  198.     return (PruneableDecList)m_sons[index];
  199.   }
  200. }