source: src/main/java/weka/classifiers/trees/adtree/TwoWayNumericSplit.java @ 7

Last change on this file since 7 was 4, checked in by gnappo, 14 years ago

Import di weka.

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