001: /*
002: * This program is free software; you can redistribute it and/or modify
003: * it under the terms of the GNU General Public License as published by
004: * the Free Software Foundation; either version 2 of the License, or
005: * (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: /*
018: * MultipleClassifiersCombiner.java
019: * Copyright (C) 2004 University of Waikato, Hamilton, New Zealand
020: *
021: */
022:
023: package weka.classifiers;
024:
025: import weka.core.Capabilities;
026: import weka.core.Option;
027: import weka.core.OptionHandler;
028: import weka.core.Utils;
029: import weka.core.Capabilities.Capability;
030:
031: import java.util.Enumeration;
032: import java.util.Vector;
033:
034: /**
035: * Abstract utility class for handling settings common to
036: * meta classifiers that build an ensemble from multiple classifiers.
037: *
038: * @author Eibe Frank (eibe@cs.waikato.ac.nz)
039: * @version $Revision: 1.6 $
040: */
041: public abstract class MultipleClassifiersCombiner extends Classifier {
042:
043: /** for serialization */
044: private static final long serialVersionUID = 2776436621129422119L;
045:
046: /** Array for storing the generated base classifiers. */
047: protected Classifier[] m_Classifiers = { new weka.classifiers.rules.ZeroR() };
048:
049: /**
050: * Returns an enumeration describing the available options
051: *
052: * @return an enumeration of all the available options
053: */
054: public Enumeration listOptions() {
055:
056: Vector newVector = new Vector(1);
057:
058: newVector
059: .addElement(new Option(
060: "\tFull class name of classifier to include, followed\n"
061: + "\tby scheme options. May be specified multiple times.\n"
062: + "\t(default: \"weka.classifiers.rules.ZeroR\")",
063: "B", 1, "-B <classifier specification>"));
064:
065: Enumeration enu = super .listOptions();
066: while (enu.hasMoreElements()) {
067: newVector.addElement(enu.nextElement());
068: }
069: return newVector.elements();
070: }
071:
072: /**
073: * Parses a given list of options. Valid options are:<p>
074: *
075: * -B classifierstring <br>
076: * Classifierstring should contain the full class name of a scheme
077: * included for selection followed by options to the classifier
078: * (required, option should be used once for each classifier).<p>
079: *
080: * @param options the list of options as an array of strings
081: * @exception Exception if an option is not supported
082: */
083: public void setOptions(String[] options) throws Exception {
084:
085: // Iterate through the schemes
086: Vector classifiers = new Vector();
087: while (true) {
088: String classifierString = Utils.getOption('B', options);
089: if (classifierString.length() == 0) {
090: break;
091: }
092: String[] classifierSpec = Utils
093: .splitOptions(classifierString);
094: if (classifierSpec.length == 0) {
095: throw new IllegalArgumentException(
096: "Invalid classifier specification string");
097: }
098: String classifierName = classifierSpec[0];
099: classifierSpec[0] = "";
100: classifiers.addElement(Classifier.forName(classifierName,
101: classifierSpec));
102: }
103: if (classifiers.size() == 0) {
104: classifiers.addElement(new weka.classifiers.rules.ZeroR());
105: }
106: Classifier[] classifiersArray = new Classifier[classifiers
107: .size()];
108: for (int i = 0; i < classifiersArray.length; i++) {
109: classifiersArray[i] = (Classifier) classifiers.elementAt(i);
110: }
111: setClassifiers(classifiersArray);
112: }
113:
114: /**
115: * Gets the current settings of the Classifier.
116: *
117: * @return an array of strings suitable for passing to setOptions
118: */
119: public String[] getOptions() {
120:
121: String[] super Options = super .getOptions();
122: int current = 0;
123: String[] options = new String[super Options.length
124: + m_Classifiers.length * 2];
125: for (int i = 0; i < m_Classifiers.length; i++) {
126: options[current++] = "-B";
127: options[current++] = "" + getClassifierSpec(i);
128: }
129: System.arraycopy(super Options, 0, options, current,
130: super Options.length);
131: return options;
132: }
133:
134: /**
135: * Returns the tip text for this property
136: * @return tip text for this property suitable for
137: * displaying in the explorer/experimenter gui
138: */
139: public String classifiersTipText() {
140: return "The base classifiers to be used.";
141: }
142:
143: /**
144: * Sets the list of possible classifers to choose from.
145: *
146: * @param classifiers an array of classifiers with all options set.
147: */
148: public void setClassifiers(Classifier[] classifiers) {
149:
150: m_Classifiers = classifiers;
151: }
152:
153: /**
154: * Gets the list of possible classifers to choose from.
155: *
156: * @return the array of Classifiers
157: */
158: public Classifier[] getClassifiers() {
159:
160: return m_Classifiers;
161: }
162:
163: /**
164: * Gets a single classifier from the set of available classifiers.
165: *
166: * @param index the index of the classifier wanted
167: * @return the Classifier
168: */
169: public Classifier getClassifier(int index) {
170:
171: return m_Classifiers[index];
172: }
173:
174: /**
175: * Gets the classifier specification string, which contains the class name of
176: * the classifier and any options to the classifier
177: *
178: * @param index the index of the classifier string to retrieve, starting from
179: * 0.
180: * @return the classifier string, or the empty string if no classifier
181: * has been assigned (or the index given is out of range).
182: */
183: protected String getClassifierSpec(int index) {
184:
185: if (m_Classifiers.length < index) {
186: return "";
187: }
188: Classifier c = getClassifier(index);
189: return c.getClass().getName() + " "
190: + Utils.joinOptions(((OptionHandler) c).getOptions());
191: }
192:
193: /**
194: * Returns combined capabilities of the base classifiers, i.e., the
195: * capabilities all of them have in common.
196: *
197: * @return the capabilities of the base classifiers
198: */
199: public Capabilities getCapabilities() {
200: Capabilities result;
201: int i;
202:
203: if (getClassifiers().length == 0) {
204: result = new Capabilities(this );
205: } else {
206: result = (Capabilities) getClassifier(0).getCapabilities()
207: .clone();
208: for (i = 1; i < getClassifiers().length; i++)
209: result.and(getClassifier(i).getCapabilities());
210: }
211:
212: // set dependencies
213: for (Capability cap : Capability.values())
214: result.enableDependency(cap);
215:
216: result.setOwner(this);
217:
218: return result;
219: }
220: }
|