TwoWayNominalSplit.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.  *    TwoWayNominalSplit.java
  18.  *    Copyright (C) 2001 Richard Kirkby
  19.  *
  20.  */
  21. package weka.classifiers.trees.adtree;
  22. import weka.core.*;
  23. import java.util.*;
  24. /**
  25.  * Class representing a two-way split on a nominal attribute, of the form:
  26.  * either 'is some_value' or 'is not some_value'.
  27.  *
  28.  * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz)
  29.  * @version $Revision: 1.2 $
  30.  */
  31. public class TwoWayNominalSplit extends Splitter {
  32.   /** The index of the attribute the split depends on */
  33.   private int attIndex;
  34.   /** The attribute value that is compared against */
  35.   private int trueSplitValue;
  36.   /** The children of this split */
  37.   private PredictionNode[] children;
  38.   /**
  39.    * Creates a new two-way nominal splitter.
  40.    *
  41.    * @param _attIndex the index of the attribute this split depeneds on
  42.    * @param _trueSplitValue the attribute value that the splitter splits on
  43.    */
  44.   public TwoWayNominalSplit(int _attIndex, int _trueSplitValue) {
  45.     attIndex = _attIndex; trueSplitValue = _trueSplitValue;
  46.     children = new PredictionNode[2];
  47.   }
  48.   /**
  49.    * Gets the number of branches of the split.
  50.    *
  51.    * @return the number of branches (always = 2)
  52.    */
  53.   public int getNumOfBranches() { 
  54.   
  55.     return 2;
  56.   }
  57.   /**
  58.    * Gets the index of the branch that an instance applies to. Returns -1 if no branches
  59.    * apply.
  60.    *
  61.    * @param i the instance
  62.    * @return the branch index
  63.    */
  64.   public int branchInstanceGoesDown(Instance inst) {
  65.     
  66.     if (inst.isMissing(attIndex)) return -1;
  67.     else if (inst.value(attIndex) == trueSplitValue) return 0;
  68.     else return 1;
  69.   }
  70.   /**
  71.    * Gets the subset of instances that apply to a particluar branch of the split. If the
  72.    * branch index is -1, the subset will consist of those instances that don't apply to
  73.    * any branch.
  74.    *
  75.    * @param branch the index of the branch
  76.    * @param sourceInstances the instances from which to find the subset 
  77.    * @return the set of instances that apply
  78.    */
  79.   public ReferenceInstances instancesDownBranch(int branch, Instances instances) {
  80.     
  81.     ReferenceInstances filteredInstances = new ReferenceInstances(instances, 1);
  82.     if (branch == -1) {
  83.       for (Enumeration e = instances.enumerateInstances(); e.hasMoreElements(); ) {
  84. Instance inst = (Instance) e.nextElement();
  85. if (inst.isMissing(attIndex)) filteredInstances.addReference(inst);
  86.       }
  87.     } else if (branch == 0) {
  88.       for (Enumeration e = instances.enumerateInstances(); e.hasMoreElements(); ) {
  89. Instance inst = (Instance) e.nextElement();
  90. if (!inst.isMissing(attIndex) && inst.value(attIndex) == trueSplitValue)
  91.   filteredInstances.addReference(inst);
  92.       }
  93.     } else {
  94.       for (Enumeration e = instances.enumerateInstances(); e.hasMoreElements(); ) {
  95. Instance inst = (Instance) e.nextElement();
  96. if (!inst.isMissing(attIndex) && inst.value(attIndex) != trueSplitValue)
  97.   filteredInstances.addReference(inst);
  98.       }
  99.     }
  100.     return filteredInstances;
  101.   }
  102.   /**
  103.    * Gets the string describing the attributes the split depends on.
  104.    * i.e. the left hand side of the description of the split.
  105.    *
  106.    * @param dataset the dataset that the split is based on
  107.    * @return a string describing the attributes
  108.    */  
  109.   public String attributeString(Instances dataset) {
  110.     
  111.     return dataset.attribute(attIndex).name();
  112.   }
  113.   /**
  114.    * Gets the string describing the comparision the split depends on for a particular
  115.    * branch. i.e. the right hand side of the description of the split.
  116.    *
  117.    * @param branchNum the branch of the split
  118.    * @param dataset the dataset that the split is based on
  119.    * @return a string describing the comparison
  120.    */
  121.   public String comparisonString(int branchNum, Instances dataset) {
  122.     Attribute att = dataset.attribute(attIndex);
  123.     if (att.numValues() != 2) 
  124.       return ((branchNum == 0 ? "= " : "!= ") + att.value(trueSplitValue));
  125.     else return ("= " + (branchNum == 0 ?
  126.  att.value(trueSplitValue) :
  127.  att.value(trueSplitValue == 0 ? 1 : 0)));
  128.   }
  129.   /**
  130.    * Tests whether two splitters are equivalent.
  131.    *
  132.    * @param compare the splitter to compare with
  133.    * @return whether or not they match
  134.    */
  135.   public boolean equalTo(Splitter compare) {
  136.     if (compare instanceof TwoWayNominalSplit) { // test object type
  137.       TwoWayNominalSplit compareSame = (TwoWayNominalSplit) compare;
  138.       return (attIndex == compareSame.attIndex &&
  139.       trueSplitValue == compareSame.trueSplitValue);
  140.     } else return false;
  141.   }
  142.   /**
  143.    * Sets the child for a branch of the split.
  144.    *
  145.    * @param branchNum the branch to set the child for
  146.    * @param childPredictor the new child
  147.    */
  148.   public void setChildForBranch(int branchNum, PredictionNode childPredictor) {
  149.     children[branchNum] = childPredictor;
  150.   }
  151.   /**
  152.    * Gets the child for a branch of the split.
  153.    *
  154.    * @param branchNum the branch to get the child for
  155.    * @return the child
  156.    */
  157.   public PredictionNode getChildForBranch(int branchNum) {
  158.     return children[branchNum];
  159.   }
  160.   /**
  161.    * Clones this node. Performs a deep copy, recursing through the tree.
  162.    *
  163.    * @return a clone
  164.    */
  165.   public Object clone() {
  166.     TwoWayNominalSplit clone = new TwoWayNominalSplit(attIndex, trueSplitValue);
  167.     clone.orderAdded = orderAdded;
  168.     if (children[0] != null)
  169.       clone.setChildForBranch(0, (PredictionNode) children[0].clone());
  170.     if (children[1] != null)
  171.       clone.setChildForBranch(1, (PredictionNode) children[1].clone());
  172.     return clone;
  173.   }
  174. }