/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* EnsembleLibraryModel.java
* Copyright (C) 2006 Robert Jung
*
*/
package weka.classifiers;
import weka.core.OptionHandler;
import weka.core.RevisionHandler;
import weka.core.RevisionUtils;
import weka.core.Utils;
import weka.gui.GenericObjectEditor;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* This class is a light wrapper that is meant to represent a
* classifier in a classifier library. This simple base class
* is intended only to store the class type and the parameters
* for a specific "type" of classifier. You will need to
* extend this class to add functionality specific to models
* that have been trained on data (as we have for Ensemble Selection)
*
* @author Robert Jung (mrbobjung@gmail.com)
* @version $Revision: 6041 $
*/
public class EnsembleLibraryModel
implements Serializable, RevisionHandler {
/** this stores the class of the classifier */
//private Class m_ModelClass;
/**
* This is the serialVersionUID that SHOULD stay the same
* so that future modified versions of this class will be
* backwards compatible with older model versions.
*/
private static final long serialVersionUID = 7932816660173443200L;
/** this is an array of options*/
protected Classifier m_Classifier;
/** the description of this classifier*/
protected String m_DescriptionText;
/** this is also saved separately */
protected String m_ErrorText;
/** a boolean variable tracking whether or not this classifier was
* able to be built successfully with the given set of options*/
protected boolean m_OptionsWereValid;
/** this is stores redundantly to speed up the many operations that
frequently need to get the model string representations (like JList
renderers) */
protected String m_StringRepresentation;
/**
* Default Constructor
*/
public EnsembleLibraryModel() {
super();
}
/**
* Initializes the class with the given classifier.
*
* @param classifier the classifier to use
*/
public EnsembleLibraryModel(Classifier classifier) {
m_Classifier = classifier;
//this may seem redundant and stupid, but it really is a good idea
//to cache the stringRepresentation to minimize the amount of work
//that needs to be done when these Models are rendered
m_StringRepresentation = toString();
updateDescriptionText();
}
/**
* This method will attempt to instantiate this classifier with the given
* options. If an exception is thrown from the setOptions method of the
* classifier then the resulting exception text will be saved in the
* description text string.
*/
public void testOptions() {
Classifier testClassifier = null;
try {
testClassifier = ((Classifier) m_Classifier.getClass().newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
setOptionsWereValid(true);
setErrorText(null);
updateDescriptionText();
try {
((OptionHandler)testClassifier).setOptions(((OptionHandler)m_Classifier).getOptions());
} catch (Exception e) {
setOptionsWereValid(false);
setErrorText(e.getMessage());
}
updateDescriptionText();
}
/**
* Returns the base classifier this library model represents.
*
* @return the base classifier
*/
public Classifier getClassifier() {
return m_Classifier;
}
/**
* getter for the string representation
*
* @return the string representation
*/
public String getStringRepresentation() {
return m_StringRepresentation;
}
/**
* setter for the description text
*
* @param descriptionText the description
*/
public void setDescriptionText(String descriptionText) {
m_DescriptionText = descriptionText;
}
/**
* getter for the string representation
*
* @return the description
*/
public String getDescriptionText() {
return m_DescriptionText;
}
/**
* setter for the error text
*
* @param errorText the error text
*/
public void setErrorText(String errorText) {
this.m_ErrorText = errorText;
}
/**
* getter for the error text
*
* @return the error text
*/
public String getErrorText() {
return m_ErrorText;
}
/**
* setter for the optionsWereValid member variable
*
* @param optionsWereValid if true, the options were valid
*/
public void setOptionsWereValid(boolean optionsWereValid) {
this.m_OptionsWereValid = optionsWereValid;
}
/**
* getter for the optionsWereValid member variable
*
* @return true if the options were valid
*/
public boolean getOptionsWereValid() {
return m_OptionsWereValid;
}
/**
* This method converts the current set of arguments and the
* class name to a string value representing the command line
* invocation
*
* @return a string representation of classname and options
*/
public String toString() {
String str = m_Classifier.getClass().getName();
str += " " + Utils.joinOptions(((OptionHandler) m_Classifier).getOptions());
return str;
}
/**
* getter for the modelClass
*
* @return the model class
*/
public Class getModelClass() {
return m_Classifier.getClass();
}
/**
* getter for the classifier options
*
* @return the classifier options
*/
public String[] getOptions() {
return ((OptionHandler)m_Classifier).getOptions();
}
/**
* Custom serialization method
*
* @param stream the stream to write the object to
* @throws IOException if something goes wrong IO-wise
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
//stream.defaultWriteObject();
//stream.writeObject(b);
//serialize the LibraryModel fields
stream.writeObject(m_Classifier);
stream.writeObject(m_DescriptionText);
stream.writeObject(m_ErrorText);
stream.writeObject(new Boolean(m_OptionsWereValid));
stream.writeObject(m_StringRepresentation);
}
/**
* Custom serialization method
*
* @param stream the stream to write to
* @throws IOException if something goes wrong IO-wise
* @throws ClassNotFoundException if class couldn't be found
*/
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
m_Classifier = (Classifier) stream.readObject();
m_DescriptionText = (String) stream.readObject();
m_ErrorText = (String) stream.readObject();
m_OptionsWereValid = ((Boolean) stream.readObject()).booleanValue();
m_StringRepresentation = (String) stream.readObject();
}
/**
* This method loops through all of the properties of a classifier to
* build the html toolTipText that will show all of the property values
* for this model.
*
* Note that this code is copied+adapted from the PropertySheetPanel
* class.
*/
public void updateDescriptionText() {
String toolTipText = new String("");
if (!m_OptionsWereValid) {
toolTipText += ""
+ "Invalid Model:
" + m_ErrorText + "
";
}
toolTipText += "
" + name + " | " + value.toString() + " |