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

« back to all changes in this revision

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