Remove.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 10k
Category:

Windows Develop

Development Platform:

Java

  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.  *    Remove.java
  18.  *    Copyright (C) 1999 Len Trigg
  19.  *
  20.  */
  21. package weka.filters.unsupervised.attribute;
  22. import weka.filters.*;
  23. import java.io.*;
  24. import java.util.*;
  25. import weka.core.*;
  26. /** 
  27.  * An instance filter that deletes a range of attributes from the dataset.<p>
  28.  *
  29.  * Valid filter-specific options are:<p>
  30.  *
  31.  * -R index1,index2-index4,...<br>
  32.  * Specify list of columns to delete. First and last are valid indexes.
  33.  * (default none)<p>
  34.  *
  35.  * -V<br>
  36.  * Invert matching sense (i.e. only keep specified columns)<p>
  37.  *
  38.  * @author Len Trigg (trigg@cs.waikato.ac.nz)
  39.  * @version $Revision: 1.1 $
  40.  */
  41. public class Remove extends Filter
  42.   implements UnsupervisedFilter, StreamableFilter, OptionHandler {
  43.   /** Stores which columns to select as a funky range */
  44.   protected Range m_SelectCols = new Range();
  45.   /**
  46.    * Stores the indexes of the selected attributes in order, once the
  47.    * dataset is seen
  48.    */
  49.   protected int [] m_SelectedAttributes;
  50.   /** 
  51.    * Contains an index of string attributes in the input format
  52.    * that will survive the filtering process 
  53.    */
  54.   protected int [] m_InputStringIndex;
  55.   /**
  56.    * Returns an enumeration describing the available options.
  57.    *
  58.    * @return an enumeration of all the available options.
  59.    */
  60.   public Enumeration listOptions() {
  61.     Vector newVector = new Vector(2);
  62.     newVector.addElement(new Option(
  63.               "tSpecify list of columns to delete. First and last are validn"
  64.       +"tindexes. (default none)",
  65.               "R", 1, "-R <index1,index2-index4,...>"));
  66.     newVector.addElement(new Option(
  67.       "tInvert matching sense (i.e. only keep specified columns)",
  68.               "V", 0, "-V"));
  69.     return newVector.elements();
  70.   }
  71.   /**
  72.    * Parses a given list of options controlling the behaviour of this object.
  73.    * Valid options are:<p>
  74.    *
  75.    * -R index1,index2-index4,...<br>
  76.    * Specify list of columns to delete. First and last are valid indexes.
  77.    * (default none)<p>
  78.    *
  79.    * -V<br>
  80.    * Invert matching sense (i.e. only keep specified columns)<p>
  81.    *
  82.    * @param options the list of options as an array of strings
  83.    * @exception Exception if an option is not supported
  84.    */
  85.   public void setOptions(String[] options) throws Exception {
  86.     String deleteList = Utils.getOption('R', options);
  87.     if (deleteList.length() != 0) {
  88.       setAttributeIndices(deleteList);
  89.     }
  90.     setInvertSelection(Utils.getFlag('V', options));
  91.     
  92.     if (getInputFormat() != null) {
  93.       setInputFormat(getInputFormat());
  94.     }
  95.   }
  96.   /**
  97.    * Gets the current settings of the filter.
  98.    *
  99.    * @return an array of strings suitable for passing to setOptions
  100.    */
  101.   public String [] getOptions() {
  102.     String [] options = new String [3];
  103.     int current = 0;
  104.     if (getInvertSelection()) {
  105.       options[current++] = "-V";
  106.     }
  107.     if (!getAttributeIndices().equals("")) {
  108.       options[current++] = "-R"; options[current++] = getAttributeIndices();
  109.     }
  110.     while (current < options.length) {
  111.       options[current++] = "";
  112.     }
  113.     return options;
  114.   }
  115.   /**
  116.    * Sets the format of the input instances.
  117.    *
  118.    * @param instanceInfo an Instances object containing the input instance
  119.    * structure (any instances contained in the object are ignored - only the
  120.    * structure is required).
  121.    * @return true if the outputFormat may be collected immediately
  122.    * @exception Exception if the format couldn't be set successfully
  123.    */
  124.   public boolean setInputFormat(Instances instanceInfo) throws Exception {
  125.     super.setInputFormat(instanceInfo);
  126.     
  127.     m_SelectCols.setUpper(instanceInfo.numAttributes() - 1);
  128.     // Create the output buffer
  129.     FastVector attributes = new FastVector();
  130.     int outputClass = -1;
  131.     m_SelectedAttributes = m_SelectCols.getSelection();
  132.     int inStrKeepLen = 0;
  133.     int [] inStrKeep = new int[m_SelectedAttributes.length];
  134.     for (int i = 0; i < m_SelectedAttributes.length; i++) {
  135.       int current = m_SelectedAttributes[i];
  136.       if (instanceInfo.classIndex() == current) {
  137. outputClass = attributes.size();
  138.       }
  139.       Attribute keep = (Attribute)instanceInfo.attribute(current).copy();
  140.       if (keep.type() == Attribute.STRING) {
  141.         inStrKeep[inStrKeepLen++] = current;
  142.       }
  143.       attributes.addElement(keep);
  144.     }
  145.     m_InputStringIndex = new int [inStrKeepLen];
  146.     System.arraycopy(inStrKeep, 0, m_InputStringIndex, 0, inStrKeepLen);
  147.     Instances outputFormat = new Instances(instanceInfo.relationName(),
  148.    attributes, 0); 
  149.     outputFormat.setClassIndex(outputClass);
  150.     setOutputFormat(outputFormat);
  151.     return true;
  152.   }
  153.   
  154.   /**
  155.    * Input an instance for filtering. Ordinarily the instance is processed
  156.    * and made available for output immediately. Some filters require all
  157.    * instances be read before producing output.
  158.    *
  159.    * @param instance the input instance
  160.    * @return true if the filtered instance may now be
  161.    * collected with output().
  162.    * @exception IllegalStateException if no input structure has been defined.
  163.    */
  164.   public boolean input(Instance instance) {
  165.     if (getInputFormat() == null) {
  166.       throw new IllegalStateException("No input instance format defined");
  167.     }
  168.     if (m_NewBatch) {
  169.       resetQueue();
  170.       m_NewBatch = false;
  171.     }
  172.     double [] vals = new double[getOutputFormat().numAttributes()];
  173.     for (int i = 0; i < m_SelectedAttributes.length; i++) {
  174.       int current = m_SelectedAttributes[i];
  175.       vals[i] = instance.value(current);
  176.     }
  177.     Instance inst = null;
  178.     if (instance instanceof SparseInstance) {
  179.       inst = new SparseInstance(instance.weight(), vals);
  180.     } else {
  181.       inst = new Instance(instance.weight(), vals);
  182.     }
  183.     copyStringValues(inst, false, instance.dataset(), m_InputStringIndex,
  184.                      getOutputFormat(), getOutputStringIndex());
  185.     inst.setDataset(getOutputFormat());
  186.     push(inst);
  187.     return true;
  188.   }
  189.   /**
  190.    * Returns a string describing this filter
  191.    *
  192.    * @return a description of the filter suitable for
  193.    * displaying in the explorer/experimenter gui
  194.    */
  195.   public String globalInfo() {
  196.     return "An instance filter that removes a range of"
  197.       + " attributes from the dataset.";
  198.   }
  199.   /**
  200.    * Returns the tip text for this property
  201.    *
  202.    * @return tip text for this property suitable for
  203.    * displaying in the explorer/experimenter gui
  204.    */
  205.   public String invertSelectionTipText() {
  206.     return "Determines whether action is to select or delete."
  207.       + " If set to true, only the specified attributes will be kept;"
  208.       + " If set to false, specified attributes will be deleted.";
  209.   }
  210.   /**
  211.    * Get whether the supplied columns are to be removed or kept
  212.    *
  213.    * @return true if the supplied columns will be kept
  214.    */
  215.   public boolean getInvertSelection() {
  216.     return !m_SelectCols.getInvert();
  217.   }
  218.   /**
  219.    * Set whether selected columns should be removed or kept. If true the 
  220.    * selected columns are kept and unselected columns are deleted. If false
  221.    * selected columns are deleted and unselected columns are kept.
  222.    *
  223.    * @param invert the new invert setting
  224.    */
  225.   public void setInvertSelection(boolean invert) {
  226.     m_SelectCols.setInvert(!invert);
  227.   }
  228.   /**
  229.    * Returns the tip text for this property
  230.    *
  231.    * @return tip text for this property suitable for
  232.    * displaying in the explorer/experimenter gui
  233.    */
  234.   public String attributeIndicesTipText() {
  235.     return "Specify range of attributes to act on."
  236.       + " This is a comma separated list of attribute indices, with"
  237.       + " "first" and "last" valid values. Specify an inclusive"
  238.       + " range with "-". E.g: "first-3,5,6-10,last".";
  239.   }
  240.   /**
  241.    * Get the current range selection.
  242.    *
  243.    * @return a string containing a comma separated list of ranges
  244.    */
  245.   public String getAttributeIndices() {
  246.     return m_SelectCols.getRanges();
  247.   }
  248.   /**
  249.    * Set which attributes are to be deleted (or kept if invert is true)
  250.    *
  251.    * @param rangeList a string representing the list of attributes.  Since
  252.    * the string will typically come from a user, attributes are indexed from
  253.    * 1. <br>
  254.    * eg: first-3,5,6-last
  255.    */
  256.   public void setAttributeIndices(String rangeList) {
  257.     m_SelectCols.setRanges(rangeList);
  258.   }
  259.   /**
  260.    * Set which attributes are to be deleted (or kept if invert is true)
  261.    *
  262.    * @param attributes an array containing indexes of attributes to select.
  263.    * Since the array will typically come from a program, attributes are indexed
  264.    * from 0.
  265.    */
  266.   public void setAttributeIndicesArray(int [] attributes) {
  267.     
  268.     setAttributeIndices(Range.indicesToRangeList(attributes));
  269.   }
  270.   /**
  271.    * Main method for testing this class.
  272.    *
  273.    * @param argv should contain arguments to the filter: use -h for help
  274.    */
  275.   public static void main(String [] argv) {
  276.     try {
  277.       if (Utils.getFlag('b', argv)) {
  278.   Filter.batchFilterFile(new Remove(), argv); 
  279.       } else {
  280. Filter.filterFile(new Remove(), argv);
  281.       }
  282.     } catch (Exception ex) {
  283.       System.out.println(ex.getMessage());
  284.     }
  285.   }
  286. }