Package weka.gui.beans

Source Code of weka.gui.beans.PredictionAppender

/*
*    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.
*/

/*
*    PredictionAppender.java
*    Copyright (C) 2003 University of Waikato, Hamilton, New Zealand
*
*/

package weka.gui.beans;

import weka.clusterers.DensityBasedClusterer;
import weka.core.Instance;
import weka.core.DenseInstance;
import weka.core.Instances;

import java.awt.BorderLayout;
import java.beans.EventSetDescriptor;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JPanel;

/**
* Bean that can can accept batch or incremental classifier events
* and produce dataset or instance events which contain instances with
* predictions appended.
*
* @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
* @version $Revision: 6804 $
*/
public class PredictionAppender
  extends JPanel
  implements DataSource, TrainingSetProducer, TestSetProducer, Visible, BeanCommon,
       EventConstraints, BatchClassifierListener,
       IncrementalClassifierListener, BatchClustererListener, Serializable {

  /** for serialization */
  private static final long serialVersionUID = -2987740065058976673L;

  /**
   * Objects listenening for dataset events
   */
  protected Vector m_dataSourceListeners = new Vector();

  /**
   * Objects listening for instances events
   */
  protected Vector m_instanceListeners = new Vector();
 
  /**
   * Objects listening for training set events
   */
  protected Vector m_trainingSetListeners = new Vector();;
 
  /**
   * Objects listening for test set events
   */
  protected Vector m_testSetListeners = new Vector();

  /**
   * Non null if this object is a target for any events.
   */
  protected Object m_listenee = null;

  /**
   * Format of instances to be produced.
   */
  protected Instances m_format;

  protected BeanVisual m_visual =
    new BeanVisual("PredictionAppender",
       BeanVisual.ICON_PATH+"PredictionAppender.gif",
       BeanVisual.ICON_PATH+"PredictionAppender_animated.gif");

  /**
   * Append classifier's predicted probabilities (if the class is discrete
   * and the classifier is a distribution classifier)
   */
  protected boolean m_appendProbabilities;

  protected transient weka.gui.Logger m_logger;

  /**
   * Global description of this bean
   *
   * @return a <code>String</code> value
   */
  public String globalInfo() {
    return "Accepts batch or incremental classifier events and "
      +"produces a new data set with classifier predictions appended.";
  }

  /**
   * Creates a new <code>PredictionAppender</code> instance.
   */
  public PredictionAppender() {
    setLayout(new BorderLayout());
    add(m_visual, BorderLayout.CENTER);
  }

  /**
   * Set a custom (descriptive) name for this bean
   *
   * @param name the name to use
   */
  public void setCustomName(String name) {
    m_visual.setText(name);
  }

  /**
   * Get the custom (descriptive) name for this bean (if one has been set)
   *
   * @return the custom name (or the default name)
   */
  public String getCustomName() {
    return m_visual.getText();
  }

  /**
   * Return a tip text suitable for displaying in a GUI
   *
   * @return a <code>String</code> value
   */
  public String appendPredictedProbabilitiesTipText() {
    return "append probabilities rather than labels for discrete class "
      +"predictions";
  }

  /**
   * Return true if predicted probabilities are to be appended rather
   * than class value
   *
   * @return a <code>boolean</code> value
   */
  public boolean getAppendPredictedProbabilities() {
    return m_appendProbabilities;
  }

  /**
   * Set whether to append predicted probabilities rather than
   * class value (for discrete class data sets)
   *
   * @param ap a <code>boolean</code> value
   */
  public void setAppendPredictedProbabilities(boolean ap) {
    m_appendProbabilities = ap;
  }

  /**
   * Add a training set listener
   *
   * @param tsl a <code>TrainingSetListener</code> value
   */
  public void addTrainingSetListener(TrainingSetListener tsl) {
    // TODO Auto-generated method stub
    m_trainingSetListeners.addElement(tsl);
    // pass on any format that we might have determined so far
    if (m_format != null) {
      TrainingSetEvent e = new TrainingSetEvent(this, m_format);
      tsl.acceptTrainingSet(e);
    }
  }

  /**
   * Remove a training set listener
   *
   * @param tsl a <code>TrainingSetListener</code> value
   */
  public void removeTrainingSetListener(TrainingSetListener tsl) {  
    m_trainingSetListeners.removeElement(tsl);
  }

  /**
   * Add a test set listener
   *
   * @param tsl a <code>TestSetListener</code> value
   */
  public void addTestSetListener(TestSetListener tsl) {
    m_testSetListeners.addElement(tsl);
//  pass on any format that we might have determined so far
    if (m_format != null) {
      TestSetEvent e = new TestSetEvent(this, m_format);
      tsl.acceptTestSet(e);
    }
  }

  /**
   * Remove a test set listener
   *
   * @param tsl a <code>TestSetListener</code> value
   */
  public void removeTestSetListener(TestSetListener tsl) {
    m_testSetListeners.removeElement(tsl);
  }
 
  /**
   * Add a datasource listener
   *
   * @param dsl a <code>DataSourceListener</code> value
   */
  public synchronized void addDataSourceListener(DataSourceListener dsl) {
    m_dataSourceListeners.addElement(dsl);
    // pass on any format that we might have determined so far
    if (m_format != null) {
      DataSetEvent e = new DataSetEvent(this, m_format);
      dsl.acceptDataSet(e);
    }
  }
 
  /**
   * Remove a datasource listener
   *
   * @param dsl a <code>DataSourceListener</code> value
   */
  public synchronized void removeDataSourceListener(DataSourceListener dsl) {
    m_dataSourceListeners.remove(dsl);
  }

  /**
   * Add an instance listener
   *
   * @param dsl a <code>InstanceListener</code> value
   */
  public synchronized void addInstanceListener(InstanceListener dsl) {
    m_instanceListeners.addElement(dsl);
    // pass on any format that we might have determined so far
    if (m_format != null) {
      InstanceEvent e = new InstanceEvent(this, m_format);
      dsl.acceptInstance(e);
    }
  }
 
  /**
   * Remove an instance listener
   *
   * @param dsl a <code>InstanceListener</code> value
   */
  public synchronized void removeInstanceListener(InstanceListener dsl) {
    m_instanceListeners.remove(dsl);
  }

  /**
   * Set the visual for this data source
   *
   * @param newVisual a <code>BeanVisual</code> value
   */
  public void setVisual(BeanVisual newVisual) {
    m_visual = newVisual;
  }

  /**
   * Get the visual being used by this data source.
   *
   */
  public BeanVisual getVisual() {
    return m_visual;
  }

  /**
   * Use the default images for a data source
   *
   */
  public void useDefaultVisual() {
    m_visual.loadIcons(BeanVisual.ICON_PATH+"PredictionAppender.gif",
           BeanVisual.ICON_PATH+"PredictionAppender_animated.gif");
  }

  protected InstanceEvent m_instanceEvent;

 
  /**
   * Accept and process an incremental classifier event
   *
   * @param e an <code>IncrementalClassifierEvent</code> value
   */
  public void acceptClassifier(IncrementalClassifierEvent e) {
    weka.classifiers.Classifier classifier = e.getClassifier();
    Instance currentI = e.getCurrentInstance();
    int status = e.getStatus();
    int oldNumAtts = 0;
    if (status == IncrementalClassifierEvent.NEW_BATCH) {
      oldNumAtts = e.getStructure().numAttributes();
    } else {
      oldNumAtts = currentI.dataset().numAttributes();
    }
    if (status == IncrementalClassifierEvent.NEW_BATCH) {
      m_instanceEvent = new InstanceEvent(this, null, 0);
      // create new header structure
      Instances oldStructure = new Instances(e.getStructure(), 0);
      //String relationNameModifier = oldStructure.relationName()
  //+"_with predictions";
      String relationNameModifier = "_with predictions";
  //+"_with predictions";
       if (!m_appendProbabilities
     || oldStructure.classAttribute().isNumeric()) {
   try {
     m_format = makeDataSetClass(oldStructure, oldStructure, classifier,
                 relationNameModifier);
   } catch (Exception ex) {
     ex.printStackTrace();
     return;
   }
       } else if (m_appendProbabilities) {
   try {
     m_format =
       makeDataSetProbabilities(oldStructure, oldStructure, classifier,
              relationNameModifier);

   } catch (Exception ex) {
     ex.printStackTrace();
     return;
   }
       }
       // Pass on the structure
       m_instanceEvent.setStructure(m_format);
       notifyInstanceAvailable(m_instanceEvent);
       return;
    }

    double[] instanceVals = new double [m_format.numAttributes()];
    Instance newInst = null;
    try {
      // process the actual instance
      for (int i = 0; i < oldNumAtts; i++) {
  instanceVals[i] = currentI.value(i);
      }
      if (!m_appendProbabilities
    || currentI.dataset().classAttribute().isNumeric()) {
  double predClass =
    classifier.classifyInstance(currentI);
  instanceVals[instanceVals.length - 1] = predClass;
      } else if (m_appendProbabilities) {
  double [] preds = classifier.distributionForInstance(currentI);
  for (int i = oldNumAtts; i < instanceVals.length; i++) {
    instanceVals[i] = preds[i-oldNumAtts];
  }     
      }     
    } catch (Exception ex) {
      ex.printStackTrace();
      return;
    } finally {
      newInst = new DenseInstance(currentI.weight(), instanceVals);
      newInst.setDataset(m_format);
      m_instanceEvent.setInstance(newInst);
      m_instanceEvent.setStatus(status);
      // notify listeners
      notifyInstanceAvailable(m_instanceEvent);
    }

    if (status == IncrementalClassifierEvent.BATCH_FINISHED) {
      // clean up
      //      m_incrementalStructure = null;
      m_instanceEvent = null;
    }
  }

  /**
   * Accept and process a batch classifier event
   *
   * @param e a <code>BatchClassifierEvent</code> value
   */
  public void acceptClassifier(BatchClassifierEvent e) {
    if (m_dataSourceListeners.size() > 0
  || m_trainingSetListeners.size() > 0
  || m_testSetListeners.size() > 0) {

      if (e.getTestSet() == null) {
        // can't append predictions
        return;
      }

      Instances testSet = e.getTestSet().getDataSet();
      Instances trainSet = e.getTrainSet().getDataSet();
      int setNum = e.getSetNumber();
      int maxNum = e.getMaxSetNumber();

      weka.classifiers.Classifier classifier = e.getClassifier();
      String relationNameModifier = "_set_"+e.getSetNumber()+"_of_"
  +e.getMaxSetNumber();
      if (!m_appendProbabilities || testSet.classAttribute().isNumeric()) {
  try {
    Instances newTestSetInstances = makeDataSetClass(testSet, trainSet,
        classifier, relationNameModifier);
    Instances newTrainingSetInstances = makeDataSetClass(trainSet, trainSet,
        classifier, relationNameModifier);
   
    if (m_trainingSetListeners.size() > 0) {
      TrainingSetEvent tse = new TrainingSetEvent(this,
    new Instances(newTrainingSetInstances, 0));
      tse.m_setNumber = setNum;
      tse.m_maxSetNumber = maxNum;
      notifyTrainingSetAvailable(tse);
      // fill in predicted values
            for (int i = 0; i < trainSet.numInstances(); i++) {
              double predClass =
          classifier.classifyInstance(trainSet.instance(i));
              newTrainingSetInstances.instance(i).setValue(newTrainingSetInstances.numAttributes()-1,
            predClass);
            }
            tse = new TrainingSetEvent(this,
          newTrainingSetInstances);
            tse.m_setNumber = setNum;
            tse.m_maxSetNumber = maxNum;
            notifyTrainingSetAvailable(tse);
    }
   
    if (m_testSetListeners.size() > 0) {
      TestSetEvent tse = new TestSetEvent(this,
    new Instances(newTestSetInstances, 0));
      tse.m_setNumber = setNum;
      tse.m_maxSetNumber = maxNum;
      notifyTestSetAvailable(tse);
    }
    if (m_dataSourceListeners.size() > 0) {
      notifyDataSetAvailable(new DataSetEvent(this, new Instances(newTestSetInstances,0)));
    }
          if (e.getTestSet().isStructureOnly()) {
      m_format = newTestSetInstances;
    }
          if (m_dataSourceListeners.size() > 0 || m_testSetListeners.size() > 0) {
            // fill in predicted values
            for (int i = 0; i < testSet.numInstances(); i++) {
              Instance tempInst = testSet.instance(i);
             
              // if the class value is missing, then copy the instance
              // and set the data set to the training data. This is
              // just in case this test data was loaded from a CSV file
              // with all missing values for a nominal class (in this
              // case we have no information on the legal class values
              // in the test data)
              if (tempInst.isMissing(tempInst.classIndex()) &&
                  !(classifier instanceof weka.classifiers.misc.InputMappedClassifier)) {
                tempInst = (Instance)testSet.instance(i).copy();
                tempInst.setDataset(trainSet);
              }
              double predClass =
          classifier.classifyInstance(tempInst);
              newTestSetInstances.instance(i).setValue(newTestSetInstances.numAttributes()-1,
            predClass);
            }
          }
    // notify listeners
          if (m_testSetListeners.size() > 0) {
            TestSetEvent tse = new TestSetEvent(this, newTestSetInstances);
            tse.m_setNumber = setNum;
            tse.m_maxSetNumber = maxNum;
            notifyTestSetAvailable(tse);
          }
          if (m_dataSourceListeners.size() > 0) {
            notifyDataSetAvailable(new DataSetEvent(this, newTestSetInstances));           
          }
    return;
  } catch (Exception ex) {
    ex.printStackTrace();
  }
      }
      if (m_appendProbabilities) {
  try {
    Instances newTestSetInstances =
      makeDataSetProbabilities(testSet, trainSet,
             classifier,relationNameModifier);
    Instances newTrainingSetInstances =
      makeDataSetProbabilities(trainSet, trainSet,
             classifier,relationNameModifier);
    if (m_trainingSetListeners.size() > 0) {
      TrainingSetEvent tse = new TrainingSetEvent(this,
    new Instances(newTrainingSetInstances, 0));
      tse.m_setNumber = setNum;
      tse.m_maxSetNumber = maxNum;
      notifyTrainingSetAvailable(tse);
//      fill in predicted probabilities
      for (int i = 0; i < trainSet.numInstances(); i++) {
        double [] preds = classifier.
        distributionForInstance(trainSet.instance(i));
        for (int j = 0; j < trainSet.classAttribute().numValues(); j++) {
    newTrainingSetInstances.instance(i).setValue(trainSet.numAttributes()+j,
        preds[j]);
        }
      }
      tse = new TrainingSetEvent(this,
          newTrainingSetInstances);
            tse.m_setNumber = setNum;
            tse.m_maxSetNumber = maxNum;
            notifyTrainingSetAvailable(tse);
    }
    if (m_testSetListeners.size() > 0) {
      TestSetEvent tse = new TestSetEvent(this,
    new Instances(newTestSetInstances, 0));
      tse.m_setNumber = setNum;
      tse.m_maxSetNumber = maxNum;
      notifyTestSetAvailable(tse);
    }
    if (m_dataSourceListeners.size() > 0) {
      notifyDataSetAvailable(new DataSetEvent(this, new Instances(newTestSetInstances,0)));
    }
          if (e.getTestSet().isStructureOnly()) {
      m_format = newTestSetInstances;
    }
          if (m_dataSourceListeners.size() > 0 || m_testSetListeners.size() > 0) {
            // fill in predicted probabilities
            for (int i = 0; i < testSet.numInstances(); i++) {
              Instance tempInst = testSet.instance(i);
             
              // if the class value is missing, then copy the instance
              // and set the data set to the training data. This is
              // just in case this test data was loaded from a CSV file
              // with all missing values for a nominal class (in this
              // case we have no information on the legal class values
              // in the test data)
              if (tempInst.isMissing(tempInst.classIndex()) &&
                  !(classifier instanceof weka.classifiers.misc.InputMappedClassifier)) {
                tempInst = (Instance)testSet.instance(i).copy();
                tempInst.setDataset(trainSet);
              }
             
              double [] preds = classifier.
              distributionForInstance(tempInst);
              for (int j = 0; j < tempInst.classAttribute().numValues(); j++) {
          newTestSetInstances.instance(i).setValue(testSet.numAttributes()+j,
              preds[j]);
              }
            }
          }
         
          // notify listeners
          if (m_testSetListeners.size() > 0) {
            TestSetEvent tse = new TestSetEvent(this, newTestSetInstances);
            tse.m_setNumber = setNum;
            tse.m_maxSetNumber = maxNum;
            notifyTestSetAvailable(tse);
          }
          if (m_dataSourceListeners.size() > 0) {
            notifyDataSetAvailable(new DataSetEvent(this, newTestSetInstances));
          }
  } catch (Exception ex) {
    ex.printStackTrace();
  }
      }
    }
  }
 
 
  /**
   * Accept and process a batch clusterer event
   *
   * @param e a <code>BatchClassifierEvent</code> value
   */
  public void acceptClusterer(BatchClustererEvent e) {
    if (m_dataSourceListeners.size() > 0
        || m_trainingSetListeners.size() > 0
  || m_testSetListeners.size() > 0) {

      if(e.getTestSet().isStructureOnly()) {
        return;
      }
      Instances testSet = e.getTestSet().getDataSet();

      weka.clusterers.Clusterer clusterer = e.getClusterer();
      String test;
      if(e.getTestOrTrain() == 0) {
        test = "test";
      } else {
        test = "training";
      }
      String relationNameModifier = "_"+test+"_"+e.getSetNumber()+"_of_"
  +e.getMaxSetNumber();
      if (!m_appendProbabilities || !(clusterer instanceof DensityBasedClusterer)) {
  if(m_appendProbabilities && !(clusterer instanceof DensityBasedClusterer)){
          System.err.println("Only density based clusterers can append probabilities. Instead cluster will be assigned for each instance.");
          if (m_logger != null) {
            m_logger.logMessage("[PredictionAppender] "
                + statusMessagePrefix() + " Only density based clusterers can "
                +"append probabilities. Instead cluster will be assigned for each "
                +"instance.");
            m_logger.statusMessage(statusMessagePrefix()
                +"WARNING: Only density based clusterers can append probabilities. "
                +"Instead cluster will be assigned for each instance.");
          }
        }
        try {
    Instances newInstances = makeClusterDataSetClass(testSet, clusterer,
                                                           relationNameModifier);

          // data source listeners get both train and test sets
          if (m_dataSourceListeners.size() > 0) {
            notifyDataSetAvailable(new DataSetEvent(this, new Instances(newInstances,0)));
          }

          if (m_trainingSetListeners.size() > 0 && e.getTestOrTrain() > 0) {
             TrainingSetEvent tse =
               new TrainingSetEvent(this, new Instances(newInstances, 0));
             tse.m_setNumber = e.getSetNumber();
             tse.m_maxSetNumber = e.getMaxSetNumber();
      notifyTrainingSetAvailable(tse);
          }

          if (m_testSetListeners.size() > 0 && e.getTestOrTrain() == 0) {
             TestSetEvent tse =
               new TestSetEvent(this, new Instances(newInstances, 0));
             tse.m_setNumber = e.getSetNumber();
             tse.m_maxSetNumber = e.getMaxSetNumber();
      notifyTestSetAvailable(tse);
          }
         
    // fill in predicted values
    for (int i = 0; i < testSet.numInstances(); i++) {
      double predCluster =
        clusterer.clusterInstance(testSet.instance(i));
      newInstances.instance(i).setValue(newInstances.numAttributes()-1,
                predCluster);
    }
    // notify listeners
          if (m_dataSourceListeners.size() > 0) {
            notifyDataSetAvailable(new DataSetEvent(this, newInstances));
          }
          if (m_trainingSetListeners.size() > 0 && e.getTestOrTrain() > 0) {
             TrainingSetEvent tse =
               new TrainingSetEvent(this, newInstances);
             tse.m_setNumber = e.getSetNumber();
             tse.m_maxSetNumber = e.getMaxSetNumber();
      notifyTrainingSetAvailable(tse);
          }
          if (m_testSetListeners.size() > 0 && e.getTestOrTrain() == 0) {
             TestSetEvent tse =
               new TestSetEvent(this, newInstances);
             tse.m_setNumber = e.getSetNumber();
             tse.m_maxSetNumber = e.getMaxSetNumber();
      notifyTestSetAvailable(tse);
          }

    return;
  } catch (Exception ex) {
    ex.printStackTrace();
  }
      }
      else{
  try {
    Instances newInstances =
      makeClusterDataSetProbabilities(testSet,
                                            clusterer,relationNameModifier);
    notifyDataSetAvailable(new DataSetEvent(this, new Instances(newInstances,0)));
         
    // fill in predicted probabilities
    for (int i = 0; i < testSet.numInstances(); i++) {
      double [] probs = clusterer.
        distributionForInstance(testSet.instance(i));
      for (int j = 0; j < clusterer.numberOfClusters(); j++) {
        newInstances.instance(i).setValue(testSet.numAttributes()+j,
            probs[j]);
      }
    }
    // notify listeners
    notifyDataSetAvailable(new DataSetEvent(this, newInstances));
  } catch (Exception ex) {
    ex.printStackTrace();
  }
      }
    }
  }

  private Instances
    makeDataSetProbabilities(Instances insts, Instances format,
           weka.classifiers.Classifier classifier,
           String relationNameModifier)
  throws Exception {
   
    // adjust structure for InputMappedClassifier (if necessary)
    if (classifier instanceof weka.classifiers.misc.InputMappedClassifier) {
      format =
        ((weka.classifiers.misc.InputMappedClassifier)classifier).
        getModelHeader(new Instances(format, 0));
    }
   
    String classifierName = classifier.getClass().getName();
    classifierName = classifierName.
      substring(classifierName.lastIndexOf('.')+1, classifierName.length());
    int numOrigAtts = insts.numAttributes();
    Instances newInstances = new Instances(insts);
    for (int i = 0; i < format.classAttribute().numValues(); i++) {
      weka.filters.unsupervised.attribute.Add addF = new
  weka.filters.unsupervised.attribute.Add();
      addF.setAttributeIndex("last");
      addF.setAttributeName(classifierName+"_prob_"+format.classAttribute().value(i));
      addF.setInputFormat(newInstances);
      newInstances = weka.filters.Filter.useFilter(newInstances, addF);
    }
    newInstances.setRelationName(insts.relationName()+relationNameModifier);
    return newInstances;
  }

  private Instances makeDataSetClass(Instances insts, Instances structure,
             weka.classifiers.Classifier classifier,
             String relationNameModifier)
  throws Exception {
   
    // adjust structure for InputMappedClassifier (if necessary)
    if (classifier instanceof weka.classifiers.misc.InputMappedClassifier) {
      structure =
        ((weka.classifiers.misc.InputMappedClassifier)classifier).
        getModelHeader(new Instances(structure, 0));
    }
   
    weka.filters.unsupervised.attribute.Add addF = new
      weka.filters.unsupervised.attribute.Add();
    addF.setAttributeIndex("last");
    String classifierName = classifier.getClass().getName();
    classifierName = classifierName.
      substring(classifierName.lastIndexOf('.')+1, classifierName.length());
    addF.setAttributeName("class_predicted_by: "+classifierName);
    if (structure.classAttribute().isNominal()) {
      String classLabels = "";
      Enumeration enu = structure.classAttribute().enumerateValues();
      classLabels += (String)enu.nextElement();
      while (enu.hasMoreElements()) {
  classLabels += ","+(String)enu.nextElement();
      }
      addF.setNominalLabels(classLabels);
    }
    addF.setInputFormat(insts);


    Instances newInstances =
      weka.filters.Filter.useFilter(insts, addF);
    newInstances.setRelationName(insts.relationName()+relationNameModifier);
    return newInstances;
  }
 
  private Instances
    makeClusterDataSetProbabilities(Instances format,
           weka.clusterers.Clusterer clusterer,
           String relationNameModifier)
  throws Exception {
    int numOrigAtts = format.numAttributes();
    Instances newInstances = new Instances(format);
    for (int i = 0; i < clusterer.numberOfClusters(); i++) {
      weka.filters.unsupervised.attribute.Add addF = new
  weka.filters.unsupervised.attribute.Add();
      addF.setAttributeIndex("last");
      addF.setAttributeName("prob_cluster"+i);
      addF.setInputFormat(newInstances);
      newInstances = weka.filters.Filter.useFilter(newInstances, addF);
    }
    newInstances.setRelationName(format.relationName()+relationNameModifier);
    return newInstances;
  }

  private Instances makeClusterDataSetClass(Instances format,
             weka.clusterers.Clusterer clusterer,
             String relationNameModifier)
  throws Exception {
   
    weka.filters.unsupervised.attribute.Add addF = new
      weka.filters.unsupervised.attribute.Add();
    addF.setAttributeIndex("last");
    String clustererName = clusterer.getClass().getName();
    clustererName = clustererName.
      substring(clustererName.lastIndexOf('.')+1, clustererName.length());
    addF.setAttributeName("assigned_cluster: "+clustererName);
    //if (format.classAttribute().isNominal()) {
    String clusterLabels = "0";
      /*Enumeration enu = format.classAttribute().enumerateValues();
      clusterLabels += (String)enu.nextElement();
      while (enu.hasMoreElements()) {
  clusterLabels += ","+(String)enu.nextElement();
      }*/
    for(int i = 1; i <= clusterer.numberOfClusters()-1; i++)
        clusterLabels += ","+i;
    addF.setNominalLabels(clusterLabels);
    //}
    addF.setInputFormat(format);


    Instances newInstances =
      weka.filters.Filter.useFilter(format, addF);
    newInstances.setRelationName(format.relationName()+relationNameModifier);
    return newInstances;
  }

  /**
   * Notify all instance listeners that an instance is available
   *
   * @param e an <code>InstanceEvent</code> value
   */
  protected void notifyInstanceAvailable(InstanceEvent e) {
    Vector l;
    synchronized (this) {
      l = (Vector)m_instanceListeners.clone();
    }
   
    if (l.size() > 0) {
      for(int i = 0; i < l.size(); i++) {
  ((InstanceListener)l.elementAt(i)).acceptInstance(e);
      }
    }
  }

  /**
   * Notify all Data source listeners that a data set is available
   *
   * @param e a <code>DataSetEvent</code> value
   */
  protected void notifyDataSetAvailable(DataSetEvent e) {
    Vector l;
    synchronized (this) {
      l = (Vector)m_dataSourceListeners.clone();
    }
   
    if (l.size() > 0) {
      for(int i = 0; i < l.size(); i++) {
  ((DataSourceListener)l.elementAt(i)).acceptDataSet(e);
      }
    }
  }
 
  /**
   * Notify all test set listeners that a test set is available
   *
   * @param e a <code>TestSetEvent</code> value
   */
  protected void notifyTestSetAvailable(TestSetEvent e) {
    Vector l;
    synchronized (this) {
      l = (Vector)m_testSetListeners.clone();
    }
   
    if (l.size() > 0) {
      for(int i = 0; i < l.size(); i++) {
  ((TestSetListener)l.elementAt(i)).acceptTestSet(e);
      }
    }
  }
 
  /**
   * Notify all test set listeners that a test set is available
   *
   * @param e a <code>TestSetEvent</code> value
   */
  protected void notifyTrainingSetAvailable(TrainingSetEvent e) {
    Vector l;
    synchronized (this) {
      l = (Vector)m_trainingSetListeners.clone();
    }
   
    if (l.size() > 0) {
      for(int i = 0; i < l.size(); i++) {
  ((TrainingSetListener)l.elementAt(i)).acceptTrainingSet(e);
      }
    }
  }

  /**
   * Set a logger
   *
   * @param logger a <code>weka.gui.Logger</code> value
   */
  public void setLog(weka.gui.Logger logger) {
    m_logger = logger;
  }

  public void stop() {
    // tell the listenee (upstream bean) to stop
    if (m_listenee instanceof BeanCommon) {
      ((BeanCommon)m_listenee).stop();
    }
  }
 
  /**
   * Returns true if. at this time, the bean is busy with some
   * (i.e. perhaps a worker thread is performing some calculation).
   *
   * @return true if the bean is busy.
   */
  public boolean isBusy() {
    return false;
  }

  /**
   * Returns true if, at this time,
   * the object will accept a connection according to the supplied
   * event name
   *
   * @param eventName the event
   * @return true if the object will accept a connection
   */
  public boolean connectionAllowed(String eventName) {
    return (m_listenee == null);
  }

  /**
   * Returns true if, at this time,
   * the object will accept a connection according to the supplied
   * EventSetDescriptor
   *
   * @param esd the EventSetDescriptor
   * @return true if the object will accept a connection
   */
  public boolean connectionAllowed(EventSetDescriptor esd) {
    return connectionAllowed(esd.getName());
  }

  /**
   * Notify this object that it has been registered as a listener with
   * a source with respect to the supplied event name
   *
   * @param eventName
   * @param source the source with which this object has been registered as
   * a listener
   */
  public synchronized void connectionNotification(String eventName,
              Object source) {
    if (connectionAllowed(eventName)) {
      m_listenee = source;
    }
  }

  /**
   * Notify this object that it has been deregistered as a listener with
   * a source with respect to the supplied event name
   *
   * @param eventName the event name
   * @param source the source with which this object has been registered as
   * a listener
   */
  public synchronized void disconnectionNotification(String eventName,
                 Object source) {
    if (m_listenee == source) {
      m_listenee = null;
      m_format = null; // assume any calculated instance format if now invalid
    }
  }

  /**
   * Returns true, if at the current time, the named event could
   * be generated. Assumes that supplied event names are names of
   * events that could be generated by this bean.
   *
   * @param eventName the name of the event in question
   * @return true if the named event could be generated at this point in
   * time
   */
  public boolean eventGeneratable(String eventName) {
    if (m_listenee == null) {
      return false;
    }

    if (m_listenee instanceof EventConstraints) {
      if (eventName.equals("instance")) {
  if (!((EventConstraints)m_listenee).
      eventGeneratable("incrementalClassifier")) {
    return false;
  }
      }
      if (eventName.equals("dataSet")
    || eventName.equals("trainingSet")
    || eventName.equals("testSet")) {
  if (((EventConstraints)m_listenee).
      eventGeneratable("batchClassifier")) {
    return true;
  }
  if (((EventConstraints)m_listenee).eventGeneratable("batchClusterer")) {
    return true;
  }
  return false;
      }
    }
    return true;
  }
 
  private String statusMessagePrefix() {
    return getCustomName() + "$" + hashCode() + "|";
  }
}
TOP

Related Classes of weka.gui.beans.PredictionAppender

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.