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