~ubuntu-branches/ubuntu/precise/weka/precise

« back to all changes in this revision

Viewing changes to weka/classifiers/trees/adtree/TwoWayNumericSplit.java

  • Committer: Bazaar Package Importer
  • Author(s): Soeren Sonnenburg
  • Date: 2008-02-24 09:18:45 UTC
  • Revision ID: james.westby@ubuntu.com-20080224091845-1l8zy6fm6xipbzsr
Tags: upstream-3.5.7+tut1
ImportĀ upstreamĀ versionĀ 3.5.7+tut1

Show diffs side-by-side

added added

removed removed

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