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.
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.
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.
18
* RandomCommittee.java
19
* Copyright (C) 2003 University of Waikato, Hamilton, New Zealand
23
package weka.classifiers.meta;
25
import weka.classifiers.Classifier;
26
import weka.classifiers.RandomizableIteratedSingleClassifierEnhancer;
27
import weka.core.Instance;
28
import weka.core.Instances;
29
import weka.core.Randomizable;
30
import weka.core.Utils;
31
import weka.core.WeightedInstancesHandler;
33
import java.util.Random;
36
<!-- globalinfo-start -->
37
* Class for building an ensemble of randomizable base classifiers. Each base classifiers is built using a different random number seed (but based one the same data). The final prediction is a straight average of the predictions generated by the individual base classifiers.
39
<!-- globalinfo-end -->
41
<!-- options-start -->
42
* Valid options are: <p/>
44
* <pre> -S <num>
48
* <pre> -I <num>
49
* Number of iterations.
53
* If set, classifier is run in debug mode and
54
* may output additional info to the console</pre>
57
* Full name of base classifier.
58
* (default: weka.classifiers.trees.RandomTree)</pre>
61
* Options specific to classifier weka.classifiers.trees.RandomTree:
64
* <pre> -K <number of attributes>
65
* Number of attributes to randomly investigate
66
* (<1 = int(log(#attributes)+1)).</pre>
68
* <pre> -M <minimum number of instances>
69
* Set minimum number of instances per leaf.</pre>
72
* Turns debugging info on.</pre>
75
* Seed for random number generator.
80
* Options after -- are passed to the designated classifier.<p>
82
* @author Eibe Frank (eibe@cs.waikato.ac.nz)
83
* @version $Revision: 1.11 $
85
public class RandomCommittee
86
extends RandomizableIteratedSingleClassifierEnhancer
87
implements WeightedInstancesHandler {
89
/** for serialization */
90
static final long serialVersionUID = -9204394360557300092L;
95
public RandomCommittee() {
97
m_Classifier = new weka.classifiers.trees.RandomTree();
101
* String describing default classifier.
103
* @return the default classifier classname
105
protected String defaultClassifierString() {
107
return "weka.classifiers.trees.RandomTree";
111
* Returns a string describing classifier
112
* @return a description suitable for
113
* displaying in the explorer/experimenter gui
115
public String globalInfo() {
117
return "Class for building an ensemble of randomizable base classifiers. Each "
118
+ "base classifiers is built using a different random number seed (but based "
119
+ "one the same data). The final prediction is a straight average of the "
120
+ "predictions generated by the individual base classifiers.";
124
* Builds the committee of randomizable classifiers.
126
* @param data the training data to be used for generating the
128
* @exception Exception if the classifier could not be built successfully
130
public void buildClassifier(Instances data) throws Exception {
132
// can classifier handle the data?
133
getCapabilities().testWithFail(data);
135
// remove instances with missing class
136
data = new Instances(data);
137
data.deleteWithMissingClass();
139
if (!(m_Classifier instanceof Randomizable)) {
140
throw new IllegalArgumentException("Base learner must implement Randomizable!");
143
m_Classifiers = Classifier.makeCopies(m_Classifier, m_NumIterations);
145
Random random = data.getRandomNumberGenerator(m_Seed);
146
for (int j = 0; j < m_Classifiers.length; j++) {
148
// Set the random number seed for the current classifier.
149
((Randomizable) m_Classifiers[j]).setSeed(random.nextInt());
151
// Build the classifier.
152
m_Classifiers[j].buildClassifier(data);
157
* Calculates the class membership probabilities for the given test
160
* @param instance the instance to be classified
161
* @return preedicted class probability distribution
162
* @exception Exception if distribution can't be computed successfully
164
public double[] distributionForInstance(Instance instance) throws Exception {
166
double [] sums = new double [instance.numClasses()], newProbs;
168
for (int i = 0; i < m_NumIterations; i++) {
169
if (instance.classAttribute().isNumeric() == true) {
170
sums[0] += m_Classifiers[i].classifyInstance(instance);
172
newProbs = m_Classifiers[i].distributionForInstance(instance);
173
for (int j = 0; j < newProbs.length; j++)
174
sums[j] += newProbs[j];
177
if (instance.classAttribute().isNumeric() == true) {
178
sums[0] /= (double)m_NumIterations;
180
} else if (Utils.eq(Utils.sum(sums), 0)) {
183
Utils.normalize(sums);
189
* Returns description of the committee.
191
* @return description of the committee as a string
193
public String toString() {
195
if (m_Classifiers == null) {
196
return "RandomCommittee: No model built yet.";
198
StringBuffer text = new StringBuffer();
199
text.append("All the base classifiers: \n\n");
200
for (int i = 0; i < m_Classifiers.length; i++)
201
text.append(m_Classifiers[i].toString() + "\n\n");
203
return text.toString();
207
* Main method for testing this class.
209
* @param argv the options
211
public static void main(String [] argv) {
212
runClassifier(new RandomCommittee(), argv);