AttributeSelection.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 12k
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.  *    AttributeSelection.java
  18.  *    Copyright (C) 1999 Mark Hall
  19.  *
  20.  */
  21. package weka.filters.supervised.attribute;
  22. import weka.filters.*;
  23. import java.io.*;
  24. import java.util.*;
  25. import weka.core.*;
  26. import weka.attributeSelection.*;
  27. /** 
  28.  * Filter for doing attribute selection.<p>
  29.  *
  30.  * Valid options are:<p>
  31.  *
  32.  * -S <"Name of search class [search options]"> <br>
  33.  * Set search method for subset evaluators. <br>
  34.  * eg. -S "weka.attributeSelection.BestFirst -S 8" <p>
  35.  *
  36.  * -E <"Name of attribute/subset evaluation class [evaluator options]"> <br>
  37.  * Set the attribute/subset evaluator. <br>
  38.  * eg. -E "weka.attributeSelection.CfsSubsetEval -L" <p>
  39.  *
  40.  * @author Mark Hall (mhall@cs.waikato.ac.nz)
  41.  * @version $Revision: 1.1 $
  42.  */
  43. public class AttributeSelection extends Filter
  44.   implements SupervisedFilter, OptionHandler {
  45.   /** the attribute selection evaluation object */
  46.   private weka.attributeSelection.AttributeSelection m_trainSelector;
  47.   /** the attribute evaluator to use */
  48.   private ASEvaluation m_ASEvaluator;
  49.   /** the search method if any */
  50.   private ASSearch m_ASSearch;
  51.   /** holds a copy of the full set of valid  options passed to the filter */
  52.   private String [] m_FilterOptions;
  53.   /** holds the selected attributes  */
  54.   private int [] m_SelectedAttributes;
  55.   /**
  56.    * Constructor
  57.    */
  58.   public AttributeSelection () {
  59.     
  60.     resetOptions();
  61.   }
  62.   /**
  63.    * Returns an enumeration describing the available options.
  64.    * @return an enumeration of all the available options.
  65.    */
  66.   public Enumeration listOptions() {
  67.     
  68.     Vector newVector = new Vector(6);
  69.     newVector.addElement(new Option("tSets search method for subset "
  70.     + "evaluators.", "S", 1,
  71.     "-S <"Name of search class"
  72.     + " [search options]">"));
  73.     newVector.addElement(new Option("tSets attribute/subset evaluator.",
  74.     "E", 1,
  75.     "-E <"Name of attribute/subset "
  76.     + "evaluation class [evaluator "
  77.     + "options]">"));
  78.     
  79.     if ((m_ASEvaluator != null) && (m_ASEvaluator instanceof OptionHandler)) {
  80.       Enumeration enum = ((OptionHandler)m_ASEvaluator).listOptions();
  81.       
  82.       newVector.addElement(new Option("", "", 0, "nOptions specific to "
  83.    + "evaluator " + m_ASEvaluator.getClass().getName() + ":"));
  84.       while (enum.hasMoreElements()) {
  85. newVector.addElement((Option)enum.nextElement());
  86.       }
  87.     }
  88.   
  89.     if ((m_ASSearch != null) && (m_ASSearch instanceof OptionHandler)) {
  90.       Enumeration enum = ((OptionHandler)m_ASSearch).listOptions();
  91.     
  92.       newVector.addElement(new Option("", "", 0, "nOptions specific to "
  93.       + "search " + m_ASSearch.getClass().getName() + ":"));
  94.       while (enum.hasMoreElements()) {
  95. newVector.addElement((Option)enum.nextElement());
  96.       }
  97.     }
  98.     return newVector.elements();
  99.   }
  100.   /**
  101.    * Parses a given list of options. Valid options are:<p>
  102.    *
  103.    * -S <"Name of search class [search options]"> <br>
  104.    * Set search method for subset evaluators. <br>
  105.    * eg. -S "weka.attributeSelection.BestFirst -S 8" <p>
  106.    *
  107.    * -E <"Name of attribute/subset evaluation class [evaluator options]"> <br>
  108.    * Set the attribute/subset evaluator. <br>
  109.    * eg. -E "weka.attributeSelection.CfsSubsetEval -L" <p>
  110.    *
  111.    * @param options the list of options as an array of strings
  112.    * @exception Exception if an option is not supported
  113.    */
  114.   public void setOptions(String[] options) throws Exception {
  115.     
  116.     String optionString;
  117.     resetOptions();
  118.     if (Utils.getFlag('X',options)) {
  119. throw new Exception("Cross validation is not a valid option"
  120.     + " when using attribute selection as a Filter.");
  121.     }
  122.     optionString = Utils.getOption('E',options);
  123.     if (optionString.length() != 0) {
  124.       optionString = optionString.trim();
  125.       // split a quoted evaluator name from its options (if any)
  126.       int breakLoc = optionString.indexOf(' ');
  127.       String evalClassName = optionString;
  128.       String evalOptionsString = "";
  129.       String [] evalOptions=null;
  130.       if (breakLoc != -1) {
  131. evalClassName = optionString.substring(0, breakLoc);
  132. evalOptionsString = optionString.substring(breakLoc).trim();
  133. evalOptions = Utils.splitOptions(evalOptionsString);
  134.       }
  135.       setEvaluator(ASEvaluation.forName(evalClassName, evalOptions));
  136.     }
  137.     if (m_ASEvaluator instanceof AttributeEvaluator) {
  138.       setSearch(new Ranker());
  139.     }
  140.     optionString = Utils.getOption('S',options);
  141.     if (optionString.length() != 0) {
  142.       optionString = optionString.trim();
  143.       int breakLoc = optionString.indexOf(' ');
  144.       String SearchClassName = optionString;
  145.       String SearchOptionsString = "";
  146.       String [] SearchOptions=null;
  147.       if (breakLoc != -1) {
  148. SearchClassName = optionString.substring(0, breakLoc);
  149. SearchOptionsString = optionString.substring(breakLoc).trim();
  150. SearchOptions = Utils.splitOptions(SearchOptionsString);
  151.       }
  152.       setSearch(ASSearch.forName(SearchClassName, SearchOptions));
  153.     }
  154.     Utils.checkForRemainingOptions(options);
  155.   }
  156.   /**
  157.    * Gets the current settings for the attribute selection (search, evaluator)
  158.    * etc.
  159.    *
  160.    * @return an array of strings suitable for passing to setOptions()
  161.    */
  162.   public String [] getOptions() {
  163.     String [] EvaluatorOptions = new String[0];
  164.     String [] SearchOptions = new String[0];
  165.     int current = 0;
  166.     if (m_ASEvaluator instanceof OptionHandler) {
  167.       EvaluatorOptions = ((OptionHandler)m_ASEvaluator).getOptions();
  168.     }
  169.     if (m_ASSearch instanceof OptionHandler) {
  170.       SearchOptions = ((OptionHandler)m_ASSearch).getOptions();
  171.     }
  172.     String [] setOptions = new String [10];
  173.     setOptions[current++]="-E";
  174.     setOptions[current++]= getEvaluator().getClass().getName()
  175.       +" "+Utils.joinOptions(EvaluatorOptions);
  176.     setOptions[current++]="-S";
  177.     setOptions[current++]=getSearch().getClass().getName() 
  178.       + " "+Utils.joinOptions(SearchOptions);
  179.     while (current < setOptions.length) {
  180.       setOptions[current++] = "";
  181.     }
  182.     
  183.     return setOptions;
  184.   }
  185.   /**
  186.    * set a string holding the name of a attribute/subset evaluator
  187.    */
  188.   public void setEvaluator(ASEvaluation evaluator) {
  189.     m_ASEvaluator = evaluator;
  190.   }
  191.   /**
  192.    * Set as string holding the name of a search class
  193.    */
  194.   public void setSearch(ASSearch search) {
  195.     m_ASSearch = search;
  196.   }
  197.   /**
  198.    * Get the name of the attribute/subset evaluator
  199.    *
  200.    * @return the name of the attribute/subset evaluator as a string
  201.    */
  202.   public ASEvaluation getEvaluator() {
  203.     
  204.       return m_ASEvaluator;
  205.   }
  206.   /**
  207.    * Get the name of the search method
  208.    *
  209.    * @return the name of the search method as a string
  210.    */
  211.   public ASSearch getSearch() {
  212.     
  213.       return m_ASSearch;
  214.   }
  215.   /**
  216.    * Input an instance for filtering. Ordinarily the instance is processed
  217.    * and made available for output immediately. Some filters require all
  218.    * instances be read before producing output.
  219.    *
  220.    * @param instance the input instance
  221.    * @return true if the filtered instance may now be
  222.    * collected with output().
  223.    * @exception IllegalStateException if no input format has been defined.
  224.    * @exception Exception if the input instance was not of the correct format 
  225.    * or if there was a problem with the filtering.
  226.    */
  227.   public boolean input(Instance instance) throws Exception {
  228.     
  229.     if (getInputFormat() == null) {
  230.       throw new IllegalStateException("No input instance format defined");
  231.     }
  232.     if (m_NewBatch) {
  233.       resetQueue();
  234.       m_NewBatch = false;
  235.     }
  236.     if (isOutputFormatDefined()) {
  237.       convertInstance(instance);
  238.       return true;
  239.     }
  240.     bufferInput(instance);
  241.     return false;
  242.   }
  243.   /**
  244.    * Signify that this batch of input to the filter is finished. If the filter
  245.    * requires all instances prior to filtering, output() may now be called
  246.    * to retrieve the filtered instances.
  247.    *
  248.    * @return true if there are instances pending output.
  249.    * @exception IllegalStateException if no input structure has been defined.
  250.    * @exception Exception if there is a problem during the attribute selection.
  251.    */
  252.   public boolean batchFinished() throws Exception {
  253.     
  254.     if (getInputFormat() == null) {
  255.       throw new IllegalStateException("No input instance format defined");
  256.     }
  257.     if (!isOutputFormatDefined()) {
  258.       m_trainSelector.setEvaluator(m_ASEvaluator);
  259.       m_trainSelector.setSearch(m_ASSearch);
  260.       m_trainSelector.SelectAttributes(getInputFormat());
  261.       //      System.out.println(m_trainSelector.toResultsString());
  262.       m_SelectedAttributes = m_trainSelector.selectedAttributes();
  263.       if (m_SelectedAttributes == null) {
  264. throw new Exception("No selected attributesn");
  265.       }
  266.      
  267.       setOutputFormat();
  268.       
  269.       // Convert pending input instances
  270.       for (int i = 0; i < getInputFormat().numInstances(); i++) {
  271. convertInstance(getInputFormat().instance(i));
  272.       }
  273.       flushInput();
  274.     }
  275.     
  276.     m_NewBatch = true;
  277.     return (numPendingOutput() != 0);
  278.   }
  279.   /**
  280.    * Set the output format. Takes the currently defined attribute set 
  281.    * m_InputFormat and calls setOutputFormat(Instances) appropriately.
  282.    */
  283.   protected void setOutputFormat() throws Exception {
  284.     Instances informat;
  285.     if (m_SelectedAttributes == null) {
  286.       setOutputFormat(null);
  287.       return;
  288.     }
  289.     FastVector attributes = new FastVector(m_SelectedAttributes.length);
  290.     int i;
  291.     if (m_ASEvaluator instanceof AttributeTransformer) {
  292.       informat = ((AttributeTransformer)m_ASEvaluator).transformedData();
  293.     } else {
  294.       informat = getInputFormat();
  295.     }
  296.     for (i=0;i < m_SelectedAttributes.length;i++) {
  297.       attributes.
  298. addElement(informat.attribute(m_SelectedAttributes[i]).copy());
  299.     }
  300.     Instances outputFormat = 
  301.       new Instances(getInputFormat().relationName(), attributes, 0);
  302.     if (!(m_ASEvaluator instanceof UnsupervisedSubsetEvaluator) &&
  303. !(m_ASEvaluator instanceof UnsupervisedAttributeEvaluator)) {
  304.       outputFormat.setClassIndex(m_SelectedAttributes.length - 1);
  305.     }
  306.     
  307.     setOutputFormat(outputFormat);  
  308.   }
  309.   /**
  310.    * Convert a single instance over. Selected attributes only are transfered.
  311.    * The converted instance is added to the end of
  312.    * the output queue.
  313.    *
  314.    * @param instance the instance to convert
  315.    */
  316.   protected void convertInstance(Instance instance) throws Exception {
  317.     int index = 0;
  318.     Instance newInstance;
  319.     double[] newVals = new double[getOutputFormat().numAttributes()];
  320.     if (m_ASEvaluator instanceof AttributeTransformer) {
  321.       Instance tempInstance = ((AttributeTransformer)m_ASEvaluator).
  322. convertInstance(instance);
  323.       for (int i = 0; i < m_SelectedAttributes.length; i++) {
  324. int current = m_SelectedAttributes[i];
  325. newVals[i] = tempInstance.value(current);
  326.       }
  327.     } else {
  328.       for (int i = 0; i < m_SelectedAttributes.length; i++) {
  329. int current = m_SelectedAttributes[i];
  330. newVals[i] = instance.value(current);
  331.       }
  332.     }
  333.     if (instance instanceof SparseInstance) {
  334.       push(new SparseInstance(instance.weight(), newVals));
  335.     } else {
  336.       push(new Instance(instance.weight(), newVals));
  337.     }
  338.   }
  339.   /**
  340.    * set options to their default values
  341.    */
  342.   protected void resetOptions() {
  343.     m_trainSelector = new weka.attributeSelection.AttributeSelection();
  344.     setEvaluator(new CfsSubsetEval());
  345.     setSearch(new BestFirst());
  346.     m_SelectedAttributes = null;
  347.     m_FilterOptions = null;
  348.   }
  349.   /**
  350.    * Main method for testing this class.
  351.    *
  352.    * @param argv should contain arguments to the filter: use -h for help
  353.    */
  354.   public static void main(String [] argv) {
  355.     
  356.     try {
  357.       if (Utils.getFlag('b', argv)) {
  358.   Filter.batchFilterFile(new AttributeSelection(), argv);
  359.       } else {
  360. Filter.filterFile(new AttributeSelection(), argv);
  361.       }
  362.     } catch (Exception ex) {
  363.       System.out.println(ex.getMessage());
  364.     }
  365.   }
  366. }