source: src/main/java/weka/classifiers/EnsembleLibraryModel.java @ 6

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

Import di weka.

File size: 10.6 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 *    EnsembleLibraryModel.java
19 *    Copyright (C) 2006 Robert Jung
20 *
21 */
22
23package weka.classifiers;
24
25import weka.core.OptionHandler;
26import weka.core.RevisionHandler;
27import weka.core.RevisionUtils;
28import weka.core.Utils;
29import weka.gui.GenericObjectEditor;
30
31import java.beans.BeanInfo;
32import java.beans.IntrospectionException;
33import java.beans.Introspector;
34import java.beans.MethodDescriptor;
35import java.beans.PropertyDescriptor;
36import java.beans.PropertyEditor;
37import java.beans.PropertyEditorManager;
38import java.io.IOException;
39import java.io.ObjectInputStream;
40import java.io.ObjectOutputStream;
41import java.io.Serializable;
42import java.lang.reflect.InvocationTargetException;
43import java.lang.reflect.Method;
44
45/**
46 * This class is a light wrapper that is meant to represent a
47 * classifier in a classifier library.  This simple base class
48 * is intended only to store the class type and the parameters
49 * for a specific "type" of classifier.  You will need to
50 * extend this class to add functionality specific to models
51 * that have been trained on data (as we have for Ensemble Selection)
52 *
53 * @author  Robert Jung (mrbobjung@gmail.com)
54 * @version $Revision: 6041 $
55 */
56public class EnsembleLibraryModel
57  implements Serializable, RevisionHandler {
58
59  /** this stores the class of the classifier */
60  //private Class m_ModelClass;
61
62  /**
63   * This is the serialVersionUID that SHOULD stay the same
64   * so that future modified versions of this class will be
65   * backwards compatible with older model versions.
66   */
67  private static final long serialVersionUID = 7932816660173443200L;
68
69  /** this is an array of options*/
70  protected Classifier m_Classifier;
71
72  /** the description of this classifier*/
73  protected String m_DescriptionText;
74
75  /** this is also saved separately */
76  protected String m_ErrorText;
77
78  /** a boolean variable tracking whether or not this classifier was
79   * able to be built successfully with the given set of options*/
80  protected boolean m_OptionsWereValid;
81
82  /** this is stores redundantly to speed up the many operations that
83   frequently need to get the model string representations (like JList
84   renderers) */
85  protected String m_StringRepresentation;
86
87  /**
88   * Default Constructor
89   */
90  public EnsembleLibraryModel() {
91    super();
92  }
93
94  /**
95   * Initializes the class with the given classifier.
96   *
97   * @param classifier  the classifier to use
98   */
99  public EnsembleLibraryModel(Classifier classifier) {
100
101    m_Classifier = classifier;
102
103    //this may seem redundant and stupid, but it really is a good idea
104    //to cache the stringRepresentation to minimize the amount of work
105    //that needs to be done when these Models are rendered
106    m_StringRepresentation = toString();
107
108    updateDescriptionText();
109  }
110
111  /**
112   * This method will attempt to instantiate this classifier with the given
113   * options. If an exception is thrown from the setOptions method of the
114   * classifier then the resulting exception text will be saved in the
115   * description text string.
116   */
117  public void testOptions() {
118
119    Classifier testClassifier = null;
120    try {
121      testClassifier = ((Classifier) m_Classifier.getClass().newInstance());
122    } catch (InstantiationException e) {
123      e.printStackTrace();
124    } catch (IllegalAccessException e) {
125      e.printStackTrace();
126    }
127
128    setOptionsWereValid(true);
129    setErrorText(null);
130    updateDescriptionText();
131
132    try {
133      ((OptionHandler)testClassifier).setOptions(((OptionHandler)m_Classifier).getOptions());
134    } catch (Exception e) {
135
136      setOptionsWereValid(false);
137      setErrorText(e.getMessage());
138    }
139
140    updateDescriptionText();
141  }
142
143  /**
144   * Returns the base classifier this library model represents.
145   *
146   * @return            the base classifier
147   */
148  public Classifier getClassifier() {
149    return m_Classifier;
150  }
151
152  /**
153   * getter for the string representation
154   *
155   * @return            the string representation
156   */
157  public String getStringRepresentation() {
158    return m_StringRepresentation;
159  }
160
161  /**
162   * setter for the description text
163   *
164   * @param descriptionText     the description
165   */
166  public void setDescriptionText(String descriptionText) {
167    m_DescriptionText = descriptionText;
168  }
169
170  /**
171   * getter for the string representation
172   *
173   * @return            the description
174   */
175  public String getDescriptionText() {
176    return m_DescriptionText;
177  }
178
179  /**
180   * setter for the error text
181   *
182   * @param errorText   the error text
183   */
184  public void setErrorText(String errorText) {
185    this.m_ErrorText = errorText;
186  }
187
188  /**
189   * getter for the error text
190   *
191   * @return            the error text
192   */
193  public String getErrorText() {
194    return m_ErrorText;
195  }
196
197  /**
198   * setter for the optionsWereValid member variable
199   *
200   * @param optionsWereValid    if true, the options were valid
201   */
202  public void setOptionsWereValid(boolean optionsWereValid) {
203    this.m_OptionsWereValid = optionsWereValid;
204  }
205
206  /**
207   * getter for the optionsWereValid member variable
208   *
209   * @return            true if the options were valid
210   */
211  public boolean getOptionsWereValid() {
212    return m_OptionsWereValid;
213  }
214
215  /**
216   * This method converts the current set of arguments and the
217   * class name to a string value representing the command line
218   * invocation
219   *
220   * @return            a string representation of classname and options
221   */
222  public String toString() {
223
224    String str = m_Classifier.getClass().getName();
225
226    str += " " + Utils.joinOptions(((OptionHandler) m_Classifier).getOptions());
227
228    return str;
229
230  }
231
232  /**
233   * getter for the modelClass
234   *
235   * @return            the model class
236   */
237  public Class getModelClass() {
238    return m_Classifier.getClass();
239  }
240
241  /**
242   * getter for the classifier options
243   *
244   * @return            the classifier options
245   */
246  public String[] getOptions() {
247    return ((OptionHandler)m_Classifier).getOptions();
248  }
249
250  /**
251   * Custom serialization method
252   *
253   * @param stream              the stream to write the object to
254   * @throws IOException        if something goes wrong IO-wise
255   */
256  private void writeObject(ObjectOutputStream stream) throws IOException {
257    //stream.defaultWriteObject();
258    //stream.writeObject(b);
259
260    //serialize the LibraryModel fields
261
262    stream.writeObject(m_Classifier);
263
264    stream.writeObject(m_DescriptionText);
265
266    stream.writeObject(m_ErrorText);
267
268    stream.writeObject(new Boolean(m_OptionsWereValid));
269
270    stream.writeObject(m_StringRepresentation);
271  }
272
273  /**
274   * Custom serialization method
275   *
276   * @param stream                      the stream to write to
277   * @throws IOException                if something goes wrong IO-wise
278   * @throws ClassNotFoundException     if class couldn't be found
279   */
280  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
281
282    m_Classifier = (Classifier) stream.readObject();
283
284    m_DescriptionText = (String) stream.readObject();
285
286    m_ErrorText = (String) stream.readObject();
287
288    m_OptionsWereValid = ((Boolean) stream.readObject()).booleanValue();
289
290    m_StringRepresentation = (String) stream.readObject();
291  }
292
293  /**
294   * This method loops through all of the properties of a classifier to
295   * build the html toolTipText that will show all of the property values
296   * for this model.
297   *
298   * Note that this code is copied+adapted from the PropertySheetPanel
299   * class.
300   */
301  public void updateDescriptionText() {
302
303    String toolTipText = new String("<html>");
304
305    if (!m_OptionsWereValid) {
306
307      toolTipText += "<font COLOR=\"#FF0000\">"
308        + "<b>Invalid Model:</b><br>" + m_ErrorText + "<br></font>";
309    }
310
311    toolTipText += "<TABLE>";
312
313    PropertyDescriptor properties[] = null;
314    MethodDescriptor methods[] = null;
315
316    try {
317      BeanInfo bi = Introspector.getBeanInfo(m_Classifier.getClass());
318      properties = bi.getPropertyDescriptors();
319      methods = bi.getMethodDescriptors();
320    } catch (IntrospectionException ex) {
321      System.err.println("LibraryModel: Couldn't introspect");
322      return;
323    }
324
325    for (int i = 0; i < properties.length; i++) {
326
327      if (properties[i].isHidden() || properties[i].isExpert()) {
328        continue;
329      }
330
331      String name = properties[i].getDisplayName();
332      Class type = properties[i].getPropertyType();
333      Method getter = properties[i].getReadMethod();
334      Method setter = properties[i].getWriteMethod();
335
336      // Only display read/write properties.
337      if (getter == null || setter == null) {
338        continue;
339      }
340
341      try {
342        Object args[] = {};
343        Object value = getter.invoke(m_Classifier, args);
344
345        PropertyEditor editor = null;
346        Class pec = properties[i].getPropertyEditorClass();
347        if (pec != null) {
348          try {
349            editor = (PropertyEditor) pec.newInstance();
350          } catch (Exception ex) {
351            // Drop through.
352          }
353        }
354        if (editor == null) {
355          editor = PropertyEditorManager.findEditor(type);
356        }
357        //editors[i] = editor;
358
359        // If we can't edit this component, skip it.
360        if (editor == null) {
361          continue;
362        }
363        if (editor instanceof GenericObjectEditor) {
364          ((GenericObjectEditor) editor).setClassType(type);
365        }
366
367        // Don't try to set null values:
368        if (value == null) {
369          continue;
370        }
371
372        toolTipText += "<TR><TD>" + name + "</TD><TD>"
373          + value.toString() + "</TD></TR>";
374
375      } catch (InvocationTargetException ex) {
376        System.err.println("Skipping property " + name
377            + " ; exception on target: " + ex.getTargetException());
378        ex.getTargetException().printStackTrace();
379        continue;
380      } catch (Exception ex) {
381        System.err.println("Skipping property " + name
382            + " ; exception: " + ex);
383        ex.printStackTrace();
384        continue;
385      }
386    }
387
388    toolTipText += "</TABLE>";
389    toolTipText += "</html>";
390    m_DescriptionText = toolTipText;
391  }
392
393  /**
394   * Returns the revision string.
395   *
396   * @return            the revision
397   */
398  public String getRevision() {
399    return RevisionUtils.extract("$Revision: 6041 $");
400  }
401}
Note: See TracBrowser for help on using the repository browser.