ReplaceMissingValues.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.  *    ReplaceMissingValues.java
  18.  *    Copyright (C) 1999 Eibe Frank
  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.  * Replaces all missing values for nominal and numeric attributes in a 
  28.  * dataset with the modes and means from the training data.
  29.  *
  30.  * @author Eibe Frank (eibe@cs.waikato.ac.nz) 
  31.  * @version $Revision: 1.1 $
  32.  */
  33. public class ReplaceMissingValues extends Filter
  34.   implements UnsupervisedFilter {
  35.   /** The modes and means */
  36.   private double[] m_ModesAndMeans = null;
  37.   /**
  38.    * Sets the format of the input instances.
  39.    *
  40.    * @param instanceInfo an Instances object containing the input 
  41.    * instance structure (any instances contained in the object are 
  42.    * ignored - only the structure is required).
  43.    * @return true if the outputFormat may be collected immediately
  44.    * @exception Exception if the input format can't be set 
  45.    * successfully
  46.    */
  47.   public boolean setInputFormat(Instances instanceInfo) 
  48.        throws Exception {
  49.     super.setInputFormat(instanceInfo);
  50.     setOutputFormat(instanceInfo);
  51.     m_ModesAndMeans = null;
  52.     return true;
  53.   }
  54.   /**
  55.    * Input an instance for filtering. Filter requires all
  56.    * training instances be read before producing output.
  57.    *
  58.    * @param instance the input instance
  59.    * @return true if the filtered instance may now be
  60.    * collected with output().
  61.    * @exception IllegalStateException if no input format has been set.
  62.    */
  63.   public boolean input(Instance instance) {
  64.     if (getInputFormat() == null) {
  65.       throw new IllegalStateException("No input instance format defined");
  66.     }
  67.     if (m_NewBatch) {
  68.       resetQueue();
  69.       m_NewBatch = false;
  70.     }
  71.     if (m_ModesAndMeans == null) {
  72.       bufferInput(instance);
  73.       return false;
  74.     } else {
  75.       convertInstance(instance);
  76.       return true;
  77.     }
  78.   }
  79.   /**
  80.    * Signify that this batch of input to the filter is finished. 
  81.    * If the filter requires all instances prior to filtering,
  82.    * output() may now be called to retrieve the filtered instances.
  83.    *
  84.    * @return true if there are instances pending output
  85.    * @exception IllegalStateException if no input structure has been defined
  86.    */
  87.   public boolean batchFinished() {
  88.     if (getInputFormat() == null) {
  89.       throw new IllegalStateException("No input instance format defined");
  90.     }
  91.     if (m_ModesAndMeans == null) {
  92.       // Compute modes and means
  93.       double sumOfWeights =  getInputFormat().sumOfWeights();
  94.       double[][] counts = new double[getInputFormat().numAttributes()][];
  95.       for (int i = 0; i < getInputFormat().numAttributes(); i++) {
  96. if (getInputFormat().attribute(i).isNominal()) {
  97.   counts[i] = new double[getInputFormat().attribute(i).numValues()];
  98.   counts[i][0] = sumOfWeights;
  99. }
  100.       }
  101.       double[] sums = new double[getInputFormat().numAttributes()];
  102.       for (int i = 0; i < sums.length; i++) {
  103. sums[i] = sumOfWeights;
  104.       }
  105.       double[] results = new double[getInputFormat().numAttributes()];
  106.       for (int j = 0; j < getInputFormat().numInstances(); j++) {
  107. Instance inst = getInputFormat().instance(j);
  108. for (int i = 0; i < inst.numValues(); i++) {
  109.   if (!inst.isMissingSparse(i)) {
  110.     double value = inst.valueSparse(i);
  111.     if (inst.attributeSparse(i).isNominal()) {
  112.       counts[inst.index(i)][(int)value] += inst.weight();
  113.       counts[inst.index(i)][0] -= inst.weight();
  114.     } else if (inst.attributeSparse(i).isNumeric()) {
  115.       results[inst.index(i)] += inst.weight() * inst.valueSparse(i);
  116.     }
  117.   } else {
  118.     if (inst.attributeSparse(i).isNominal()) {
  119.       counts[inst.index(i)][0] -= inst.weight();
  120.     } else if (inst.attributeSparse(i).isNumeric()) {
  121.       sums[inst.index(i)] -= inst.weight();
  122.     }
  123.   }
  124. }
  125.       }
  126.       m_ModesAndMeans = new double[getInputFormat().numAttributes()];
  127.       for (int i = 0; i < getInputFormat().numAttributes(); i++) {
  128. if (getInputFormat().attribute(i).isNominal()) {
  129.   m_ModesAndMeans[i] = (double)Utils.maxIndex(counts[i]);
  130. } else if (getInputFormat().attribute(i).isNumeric()) {
  131.   if (Utils.gr(sums[i], 0)) {
  132.     m_ModesAndMeans[i] = results[i] / sums[i];
  133.   }
  134. }
  135.       }
  136.       // Convert pending input instances
  137.       for(int i = 0; i < getInputFormat().numInstances(); i++) {
  138. convertInstance(getInputFormat().instance(i));
  139.       }
  140.     } 
  141.     // Free memory
  142.     flushInput();
  143.     m_NewBatch = true;
  144.     return (numPendingOutput() != 0);
  145.   }
  146.   /**
  147.    * Convert a single instance over. The converted instance is 
  148.    * added to the end of the output queue.
  149.    *
  150.    * @param instance the instance to convert
  151.    */
  152.   private void convertInstance(Instance instance) {
  153.   
  154.     Instance inst = null;
  155.     if (instance instanceof SparseInstance) {
  156.       double []vals = new double[instance.numValues()];
  157.       int []indices = new int[instance.numValues()];
  158.       int num = 0;
  159.       for (int j = 0; j < instance.numValues(); j++) {
  160. if (instance.isMissingSparse(j) &&
  161.     (instance.attributeSparse(j).isNominal() ||
  162.      instance.attributeSparse(j).isNumeric())) {
  163.   if (m_ModesAndMeans[instance.index(j)] != 0.0) {
  164.     vals[num] = m_ModesAndMeans[instance.index(j)];
  165.     indices[num] = instance.index(j);
  166.     num++;
  167.   } 
  168. } else {
  169.   vals[num] = instance.valueSparse(j);
  170.   indices[num] = instance.index(j);
  171.   num++;
  172. }
  173.       } 
  174.       if (num == instance.numValues()) {
  175. inst = new SparseInstance(instance.weight(), vals, indices,
  176.                                   instance.numAttributes());
  177.       } else {
  178. double []tempVals = new double[num];
  179. int []tempInd = new int[num];
  180. System.arraycopy(vals, 0, tempVals, 0, num);
  181. System.arraycopy(indices, 0, tempInd, 0, num);
  182. inst = new SparseInstance(instance.weight(), tempVals, tempInd,
  183.                                   instance.numAttributes());
  184.       }
  185.     } else {
  186.       double []vals = new double[getInputFormat().numAttributes()];
  187.       for (int j = 0; j < instance.numAttributes(); j++) {
  188. if (instance.isMissing(j) &&
  189.     (getInputFormat().attribute(j).isNominal() ||
  190.      getInputFormat().attribute(j).isNumeric())) {
  191.   vals[j] = m_ModesAndMeans[j]; 
  192. } else {
  193.   vals[j] = instance.value(j);
  194. }
  195.       } 
  196.       inst = new Instance(instance.weight(), vals);
  197.     } 
  198.     inst.setDataset(instance.dataset());
  199.     push(inst);
  200.   }
  201.   /**
  202.    * Main method for testing this class.
  203.    *
  204.    * @param argv should contain arguments to the filter: 
  205.    * use -h for help
  206.    */
  207.   public static void main(String [] argv) {
  208.     try {
  209.       if (Utils.getFlag('b', argv)) {
  210.   Filter.batchFilterFile(new ReplaceMissingValues(), argv);
  211.       } else {
  212. Filter.filterFile(new ReplaceMissingValues(), argv);
  213.       }
  214.     } catch (Exception ex) {
  215.       System.out.println(ex.getMessage());
  216.     }
  217.   }
  218. }