EmptyAttributeFilter.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 6k
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.  *    EmptyAttributeFilter.java
  18.  *    Copyright (C) 2000 Intelligenesis Corp.
  19.  *
  20.  */
  21. package weka.filters;
  22. import weka.core.Instances;
  23. import weka.core.Instance;
  24. import weka.core.FastVector;
  25. import weka.core.SparseInstance;
  26. import weka.core.Utils;
  27. /** 
  28.  * Removes all attributes that do not contain more than one distinct
  29.  * value.  This determination is made based on the first batch of
  30.  * instances seen. If an attribute contains one distinct value and
  31.  * missing values, this is still taken as being empty.
  32.  *
  33.  * @author Stuart Inglis (stuart@intelligenesis.net)
  34.  * @version $Revision: 1.7 $ 
  35.  */
  36. public class EmptyAttributeFilter extends Filter {
  37.   /** The minimum values for numeric attributes. */
  38.   private double [] m_MinArray;
  39.   
  40.   /** The maximum values for numeric attributes. */
  41.   private double [] m_MaxArray;
  42.   /** An array of attribute indices that shall be kept. */
  43.   private boolean [] m_Keep;
  44.   /**
  45.    * Sets the format of the input instances.
  46.    *
  47.    * @param instanceInfo an Instances object containing the input 
  48.    * instance structure (any instances contained in the object are 
  49.    * ignored - only the structure is required).
  50.    * @return true if the outputFormat may be collected immediately
  51.    * @exception Exception if the input format can't be set 
  52.    * successfully
  53.    */
  54.   public boolean setInputFormat(Instances instanceInfo) 
  55.        throws Exception {
  56.     super.setInputFormat(instanceInfo);
  57.     m_MinArray = m_MaxArray = null;
  58.     return false;
  59.   }
  60.   /**
  61.    * Input an instance for filtering. Filter requires all
  62.    * training instances be read before producing output.
  63.    *
  64.    * @param instance the input instance
  65.    * @return true if the filtered instance may now be
  66.    * collected with output().
  67.    * @exception IllegalStateException if no input format has been defined.
  68.    */
  69.   public boolean input(Instance instance) {
  70.     if (getInputFormat() == null) {
  71.       throw new IllegalStateException("No input instance format defined");
  72.     }
  73.     if (m_NewBatch) {
  74.       resetQueue();
  75.       m_NewBatch = false;
  76.     }
  77.     
  78.     bufferInput(instance);
  79.     return false;
  80.   }
  81.   /**
  82.    * Signify that this batch of input to the filter is finished. 
  83.    * If the filter requires all instances prior to filtering,
  84.    * output() may now be called to retrieve the filtered instances.
  85.    *
  86.    * @return true if there are instances pending output
  87.    * @exception IllegalStateException if no input structure has been defined
  88.    */
  89.   public boolean batchFinished() {
  90.     if (getInputFormat() == null) {
  91.       throw new IllegalStateException("No input instance format defined");
  92.     }
  93.     if (m_MinArray == null) {
  94.    
  95.       // Compute minimums and maximums
  96.       Instances in = getInputFormat();
  97.       m_MinArray = new double[in.numAttributes()];
  98.       m_MaxArray = new double[in.numAttributes()];
  99.       m_Keep = new boolean[in.numAttributes()];
  100.       for (int i = 0; i < in.numAttributes(); i++) {
  101. m_MinArray[i] = Double.NaN;
  102.       }
  103.       for (int j = 0; j < in.numInstances(); j++) {
  104. double [] value = in.instance(j).toDoubleArray();
  105. for (int i = 0; i < in.numAttributes(); i++) {
  106.           if (!in.attribute(i).isString() &&
  107.               !Instance.isMissingValue(value[i])) {
  108.             if (Double.isNaN(m_MinArray[i])) {
  109.               m_MinArray[i] = m_MaxArray[i] = value[i];
  110.             } else {
  111.               if (value[i] < m_MinArray[i]) {
  112.                 m_MinArray[i] = value[i];
  113.               }
  114.               if (value[i] > m_MaxArray[i]) {
  115.                 m_MaxArray[i] = value[i];
  116.               }
  117.             }
  118.   }
  119.       }
  120.       FastVector attributes = new FastVector();
  121.       for (int i = 0; i < in.numAttributes(); i++) {
  122.         if (in.attribute(i).isString() || 
  123.             (m_MinArray[i] < m_MaxArray[i])) {
  124.           attributes.addElement(in.attribute(i).copy());
  125.           m_Keep[i] = true;
  126.         }
  127.       }
  128.       Instances outputFormat = new Instances(in.relationName(),
  129.      attributes, 0); 
  130.       setOutputFormat(outputFormat);
  131.       // Convert pending input instances
  132.       for(int i = 0; i < in.numInstances(); i++) {
  133. convertInstance(in.instance(i));
  134.       }
  135.       // Free memory
  136.       flushInput();
  137.     } 
  138.     m_NewBatch = true;
  139.     return (numPendingOutput() != 0);
  140.   }
  141.   /**
  142.    * Convert a single instance over. The converted instance is 
  143.    * added to the end of the output queue.
  144.    *
  145.    * @param instance the instance to convert
  146.    */
  147.   private void convertInstance(Instance instance) {
  148.   
  149.     int index = 0;
  150.     double [] vals = new double [outputFormatPeek().numAttributes()];
  151.     for(int i = 0; i < getInputFormat().numAttributes(); i++) {
  152.       if (m_Keep[i]) {
  153.         if (instance.isMissing(i)) {
  154.           vals[index] = Instance.missingValue();
  155.         } else {
  156.           vals[index] = instance.value(i);
  157.         }
  158.         index++;
  159.       }
  160.     }
  161.     Instance inst = null;
  162.     if (instance instanceof SparseInstance) {
  163.       inst = new SparseInstance(instance.weight(), vals);
  164.     } else {
  165.       inst = new Instance(instance.weight(), vals);
  166.     }
  167.     copyStringValues(inst, false, instance.dataset(), getInputStringIndex(),
  168.                      getOutputFormat(), getOutputStringIndex());
  169.     inst.setDataset(getOutputFormat());
  170.     push(inst);
  171.   }
  172.   /**
  173.    * Main method for testing this class.
  174.    *
  175.    * @param argv should contain arguments to the filter: 
  176.    * use -h for help
  177.    */
  178.   public static void main(String [] argv) {
  179.     try {
  180.       if (Utils.getFlag('b', argv)) {
  181.   Filter.batchFilterFile(new EmptyAttributeFilter(), argv);
  182.       } else {
  183. Filter.filterFile(new EmptyAttributeFilter(), argv);
  184.       }
  185.     } catch (Exception ex) {
  186. // ex.printStackTrace();
  187.       System.out.println(ex.getMessage());
  188.     }
  189.   }
  190. }