NormalizationFilter.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 7k
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.  *    NormalizationFilter.java
  18.  *    Copyright (C) 1999 Eibe Frank
  19.  *
  20.  */
  21. package weka.filters;
  22. import java.io.*;
  23. import java.util.*;
  24. import weka.core.*;
  25. /** 
  26.  * Normalizes all numeric values in the given dataset. The resulting
  27.  * values are in [0,1] for the data used to compute the normalization
  28.  * intervals.
  29.  *
  30.  * @author Eibe Frank (eibe@cs.waikato.ac.nz) 
  31.  * @version $Revision: 1.10 $
  32.  */
  33. public class NormalizationFilter extends Filter {
  34.   /** The minimum values for numeric attributes. */
  35.   private double [] m_MinArray;
  36.   
  37.   /** The maximum values for numeric attributes. */
  38.   private double [] m_MaxArray;
  39.   /**
  40.    * Sets the format of the input instances.
  41.    *
  42.    * @param instanceInfo an Instances object containing the input 
  43.    * instance structure (any instances contained in the object are 
  44.    * ignored - only the structure is required).
  45.    * @return true if the outputFormat may be collected immediately
  46.    * @exception Exception if the input format can't be set 
  47.    * successfully
  48.    */
  49.   public boolean setInputFormat(Instances instanceInfo) 
  50.        throws Exception {
  51.     super.setInputFormat(instanceInfo);
  52.     setOutputFormat(instanceInfo);
  53.     m_MinArray = m_MaxArray = null;
  54.     return true;
  55.   }
  56.   /**
  57.    * Input an instance for filtering. Filter requires all
  58.    * training instances be read before producing output.
  59.    *
  60.    * @param instance the input instance
  61.    * @return true if the filtered instance may now be
  62.    * collected with output().
  63.    * @exception IllegalStateException if no input format has been set.
  64.    */
  65.   public boolean input(Instance instance) {
  66.     if (getInputFormat() == null) {
  67.       throw new IllegalStateException("No input instance format defined");
  68.     }
  69.     if (m_NewBatch) {
  70.       resetQueue();
  71.       m_NewBatch = false;
  72.     }
  73.     if (m_MinArray == null) {
  74.       bufferInput(instance);
  75.       return false;
  76.     } else {
  77.       convertInstance(instance);
  78.       return true;
  79.     }
  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.       Instances input = getInputFormat();
  95.       // Compute minimums and maximums
  96.       m_MinArray = new double[input.numAttributes()];
  97.       m_MaxArray = new double[input.numAttributes()];
  98.       for (int i = 0; i < input.numAttributes(); i++) {
  99. m_MinArray[i] = Double.NaN;
  100.       }
  101.       for (int j = 0; j < input.numInstances(); j++) {
  102. double[] value = input.instance(j).toDoubleArray();
  103. for (int i = 0; i < input.numAttributes(); i++) {
  104.   if (input.attribute(i).isNumeric()) {
  105.     if (!Instance.isMissingValue(value[i])) {
  106.       if (Double.isNaN(m_MinArray[i])) {
  107. m_MinArray[i] = m_MaxArray[i] = value[i];
  108.       } else {
  109. if (value[i] < m_MinArray[i]) {
  110.   m_MinArray[i] = value[i];
  111. }
  112. if (value[i] > m_MaxArray[i]) {
  113.   m_MaxArray[i] = value[i];
  114. }
  115.       }
  116.     }
  117.   }
  118.       }
  119.       // Convert pending input instances
  120.       for(int i = 0; i < input.numInstances(); i++) {
  121. convertInstance(input.instance(i));
  122.       }
  123.     } 
  124.     // Free memory
  125.     flushInput();
  126.     m_NewBatch = true;
  127.     return (numPendingOutput() != 0);
  128.   }
  129.   /**
  130.    * Convert a single instance over. The converted instance is 
  131.    * added to the end of the output queue.
  132.    *
  133.    * @param instance the instance to convert
  134.    */
  135.   private void convertInstance(Instance instance) {
  136.   
  137.     Instance inst = null;
  138.     if (instance instanceof SparseInstance) {
  139.       double[] newVals = new double[instance.numAttributes()];
  140.       int[] newIndices = new int[instance.numAttributes()];
  141.       double[] vals = instance.toDoubleArray();
  142.       int ind = 0;
  143.       for (int j = 0; j < instance.numAttributes(); j++) {
  144. double value;
  145. if (instance.attribute(j).isNumeric() &&
  146.     (!Instance.isMissingValue(vals[j]))) {
  147.   if (Double.isNaN(m_MinArray[j]) ||
  148.       (m_MaxArray[j] == m_MinArray[j])) {
  149.     value = 0;
  150.   } else {
  151.     value = (vals[j] - m_MinArray[j]) / 
  152.       (m_MaxArray[j] - m_MinArray[j]);
  153.   }
  154.   if (value != 0.0) {
  155.     newVals[ind] = value;
  156.     newIndices[ind] = j;
  157.     ind++;
  158.   }
  159. } else {
  160.   value = vals[j];
  161.   if (value != 0.0) {
  162.     newVals[ind] = value;
  163.     newIndices[ind] = j;
  164.     ind++;
  165.   }
  166. }
  167.       }
  168.       double[] tempVals = new double[ind];
  169.       int[] tempInd = new int[ind];
  170.       System.arraycopy(newVals, 0, tempVals, 0, ind);
  171.       System.arraycopy(newIndices, 0, tempInd, 0, ind);
  172.       inst = new SparseInstance(instance.weight(), tempVals, tempInd,
  173.                                 instance.numAttributes());
  174.     } else {
  175.       double[] vals = instance.toDoubleArray();
  176.       for (int j = 0; j < getInputFormat().numAttributes(); j++) {
  177. if (instance.attribute(j).isNumeric() &&
  178.     (!Instance.isMissingValue(vals[j]))) {
  179.   if (Double.isNaN(m_MinArray[j]) ||
  180.       (m_MaxArray[j] == m_MinArray[j])) {
  181.     vals[j] = 0;
  182.   } else {
  183.     vals[j] = (vals[j] - m_MinArray[j]) / 
  184.       (m_MaxArray[j] - m_MinArray[j]);
  185.   }
  186. }
  187.       }
  188.       inst = new Instance(instance.weight(), vals);
  189.     }
  190.     inst.setDataset(instance.dataset());
  191.     push(inst);
  192.   }
  193.   /**
  194.    * Main method for testing this class.
  195.    *
  196.    * @param argv should contain arguments to the filter: 
  197.    * use -h for help
  198.    */
  199.   public static void main(String [] argv) {
  200.     try {
  201.       if (Utils.getFlag('b', argv)) {
  202.   Filter.batchFilterFile(new NormalizationFilter(), argv);
  203.       } else {
  204. Filter.filterFile(new NormalizationFilter(), argv);
  205.       }
  206.     } catch (Exception ex) {
  207.       System.out.println(ex.getMessage());
  208.     }
  209.   }
  210. }