source: branches/MetisMQI/src/main/java/weka/filters/unsupervised/attribute/RemoveType.java

Last change on this file was 29, checked in by gnappo, 15 years ago

Taggata versione per la demo e aggiunto branch.

File size: 12.0 KB
Line 
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/*
18 *    RemoveType.java
19 *    Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.filters.unsupervised.attribute;
24
25import weka.core.Attribute;
26import weka.core.Capabilities;
27import weka.core.Instance; 
28import weka.core.DenseInstance;
29import weka.core.Instances;
30import weka.core.Option;
31import weka.core.OptionHandler;
32import weka.core.RevisionUtils;
33import weka.core.SelectedTag;
34import weka.core.Tag;
35import weka.core.Utils;
36import weka.core.Capabilities.Capability;
37import weka.filters.Filter;
38import weka.filters.StreamableFilter;
39import weka.filters.UnsupervisedFilter;
40
41import java.util.Enumeration;
42import java.util.Vector;
43
44/**
45 <!-- globalinfo-start -->
46 * Removes attributes of a given type.
47 * <p/>
48 <!-- globalinfo-end -->
49 *
50 <!-- options-start -->
51 * Valid options are: <p/>
52 *
53 * <pre> -T &lt;nominal|numeric|string|date|relational&gt;
54 *  Attribute type to delete. Valid options are "nominal",
55 *  "numeric", "string", "date" and "relational".
56 *  (default "string")</pre>
57 *
58 * <pre> -V
59 *  Invert matching sense (i.e. only keep specified columns)</pre>
60 *
61 <!-- options-end -->
62 *
63 * @author Richard Kirkby (rkirkby@cs.waikato.ac.nz)
64 * @version $Revision: 5987 $
65 */
66public class RemoveType 
67  extends Filter
68  implements UnsupervisedFilter, StreamableFilter, OptionHandler {
69
70  /** for serialization */
71  static final long serialVersionUID = -3563999462782486279L;
72 
73  /** The attribute filter used to do the filtering */
74  protected Remove m_attributeFilter = new Remove();
75
76  /** The type of attribute to delete */
77  protected int m_attTypeToDelete = Attribute.STRING;
78
79  /** Whether to invert selection */
80  protected boolean m_invert = false;
81 
82  /** Tag allowing selection of attribute type to delete */
83  public static final Tag [] TAGS_ATTRIBUTETYPE = {
84    new Tag(Attribute.NOMINAL, "Delete nominal attributes"),
85    new Tag(Attribute.NUMERIC, "Delete numeric attributes"),
86    new Tag(Attribute.STRING, "Delete string attributes"),
87    new Tag(Attribute.DATE, "Delete date attributes"),
88    new Tag(Attribute.RELATIONAL, "Delete relational attributes")
89  };
90
91  /**
92   * Returns the Capabilities of this filter.
93   *
94   * @return            the capabilities of this object
95   * @see               Capabilities
96   */
97  public Capabilities getCapabilities() {
98    Capabilities result = super.getCapabilities();
99    result.disableAll();
100
101    // attributes
102    result.enable(Capability.NOMINAL_ATTRIBUTES);
103    result.enable(Capability.NUMERIC_ATTRIBUTES);
104    result.enable(Capability.DATE_ATTRIBUTES);
105    result.enable(Capability.STRING_ATTRIBUTES);
106    result.enable(Capability.RELATIONAL_ATTRIBUTES);
107    result.enable(Capability.MISSING_VALUES);
108   
109    // class
110    result.enableAllClasses();
111    result.enable(Capability.MISSING_CLASS_VALUES);
112    result.enable(Capability.NO_CLASS);
113   
114    return result;
115  }
116
117  /**
118   * Sets the format of the input instances.
119   *
120   * @param instanceInfo an Instances object containing the input instance
121   * structure (any instances contained in the object are ignored - only the
122   * structure is required).
123   * @return true if the outputFormat may be collected immediately
124   * @throws Exception if the inputFormat can't be set successfully
125   */ 
126  public boolean setInputFormat(Instances instanceInfo) throws Exception {
127   
128    super.setInputFormat(instanceInfo);
129
130    int[] attsToDelete = new int[instanceInfo.numAttributes()];
131    int numToDelete = 0;
132    for (int i=0; i<instanceInfo.numAttributes(); i++) {
133      if ((i == instanceInfo.classIndex() && !m_invert)) {
134        continue; // skip class
135      }
136      if (instanceInfo.attribute(i).type() == m_attTypeToDelete)
137        attsToDelete[numToDelete++] = i;
138    }
139
140    int[] finalAttsToDelete = new int[numToDelete];
141    System.arraycopy(attsToDelete, 0, finalAttsToDelete, 0, numToDelete);
142   
143    m_attributeFilter.setAttributeIndicesArray(finalAttsToDelete);
144    m_attributeFilter.setInvertSelection(m_invert);
145   
146    boolean result = m_attributeFilter.setInputFormat(instanceInfo);
147    Instances afOutputFormat = m_attributeFilter.getOutputFormat();
148   
149    // restore old relation name to hide attribute filter stamp
150    afOutputFormat.setRelationName(instanceInfo.relationName());
151
152    setOutputFormat(afOutputFormat);
153    return result;
154  }
155
156  /**
157   * Input an instance for filtering.
158   *
159   * @param instance the input instance
160   * @return true if the filtered instance may now be
161   * collected with output().
162   */
163  public boolean input(Instance instance) {
164   
165    return m_attributeFilter.input(instance);
166  }
167
168  /**
169   * Signify that this batch of input to the filter is finished.
170   *
171   * @return true if there are instances pending output
172   * @throws Exception if something goes wrong
173   */ 
174  public boolean batchFinished() throws Exception {
175
176    return m_attributeFilter.batchFinished();
177  }
178
179  /**
180   * Output an instance after filtering and remove from the output queue.
181   *
182   * @return the instance that has most recently been filtered (or null if
183   * the queue is empty).
184   */
185  public Instance output() {
186
187    return m_attributeFilter.output();
188  }
189
190  /**
191   * Output an instance after filtering but do not remove from the
192   * output queue.
193   *
194   * @return the instance that has most recently been filtered (or null if
195   * the queue is empty).
196   */
197  public Instance outputPeek() {
198
199    return m_attributeFilter.outputPeek();
200  }
201
202  /**
203   * Returns the number of instances pending output
204   *
205   * @return the number of instances  pending output
206   */ 
207  public int numPendingOutput() {
208 
209    return m_attributeFilter.numPendingOutput();
210  }
211 
212  /**
213   * Returns whether the output format is ready to be collected
214   *
215   * @return true if the output format is set
216   */ 
217  public boolean isOutputFormatDefined() {
218
219    return m_attributeFilter.isOutputFormatDefined();
220  }
221
222  /**
223   * Returns an enumeration describing the available options.
224   *
225   * @return an enumeration of all the available options.
226   */
227  public Enumeration listOptions() {
228
229    Vector newVector = new Vector(2);
230
231    newVector.addElement(new Option(
232        "\tAttribute type to delete. Valid options are \"nominal\", \n"
233        + "\t\"numeric\", \"string\", \"date\" and \"relational\".\n"
234        + "\t(default \"string\")",
235        "T", 1, "-T <nominal|numeric|string|date|relational>"));
236
237    newVector.addElement(new Option(
238        "\tInvert matching sense (i.e. only keep specified columns)",
239        "V", 0, "-V"));
240
241    return newVector.elements();
242  }
243
244  /**
245   * Parses a given list of options. <p/>
246   *
247   <!-- options-start -->
248   * Valid options are: <p/>
249   *
250   * <pre> -T &lt;nominal|numeric|string|date|relational&gt;
251   *  Attribute type to delete. Valid options are "nominal",
252   *  "numeric", "string", "date" and "relational".
253   *  (default "string")</pre>
254   *
255   * <pre> -V
256   *  Invert matching sense (i.e. only keep specified columns)</pre>
257   *
258   <!-- options-end -->
259   *
260   * @param options the list of options as an array of strings
261   * @throws Exception if an option is not supported
262   */
263  public void setOptions(String[] options) throws Exception {
264   
265    String tString = Utils.getOption('T', options);
266    if (tString.length() != 0) setAttributeTypeString(tString);
267    setInvertSelection(Utils.getFlag('V', options));
268
269    if (getInputFormat() != null) {
270      setInputFormat(getInputFormat());
271    }
272  }
273
274  /**
275   * Gets the current settings of the filter.
276   *
277   * @return an array of strings suitable for passing to setOptions
278   */
279  public String [] getOptions() {
280
281    String [] options = new String [3];
282    int current = 0;
283
284    if (getInvertSelection()) {
285      options[current++] = "-V";
286    }
287    options[current++] = "-T";
288    options[current++] = getAttributeTypeString();
289   
290    while (current < options.length) {
291      options[current++] = "";
292    }
293    return options;
294  }
295
296  /**
297   * Returns a string describing this filter
298   *
299   * @return a description of the filter suitable for
300   * displaying in the explorer/experimenter gui
301   */
302  public String globalInfo() {
303
304    return "Removes attributes of a given type.";
305  }
306
307  /**
308   * Returns the tip text for this property
309   *
310   * @return tip text for this property suitable for
311   * displaying in the explorer/experimenter gui
312   */
313  public String attributeTypeTipText() {
314
315    return "The type of attribute to remove.";
316  }
317
318  /**
319   * Sets the attribute type to be deleted by the filter.
320   *
321   * @param type a TAGS_ATTRIBUTETYPE of the new type the filter should delete
322   */
323  public void setAttributeType(SelectedTag type) {
324   
325    if (type.getTags() == TAGS_ATTRIBUTETYPE) {
326      m_attTypeToDelete = type.getSelectedTag().getID();
327    }
328  }
329
330  /**
331   * Gets the attribute type to be deleted by the filter.
332   *
333   * @return the attribute type as a selected tag TAGS_ATTRIBUTETYPE
334   */
335  public SelectedTag getAttributeType() {
336
337    return new SelectedTag(m_attTypeToDelete, TAGS_ATTRIBUTETYPE);
338  }
339
340  /**
341   * Returns the tip text for this property
342   *
343   * @return tip text for this property suitable for
344   * displaying in the explorer/experimenter gui
345   */
346  public String invertSelectionTipText() {
347
348    return "Determines whether action is to select or delete."
349      + " If set to true, only the specified attributes will be kept;"
350      + " If set to false, specified attributes will be deleted.";
351  }
352
353  /**
354   * Get whether the supplied columns are to be removed or kept
355   *
356   * @return true if the supplied columns will be kept
357   */
358  public boolean getInvertSelection() {
359
360    return m_invert;
361  }
362
363  /**
364   * Set whether selected columns should be removed or kept. If true the
365   * selected columns are kept and unselected columns are deleted. If false
366   * selected columns are deleted and unselected columns are kept.
367   *
368   * @param invert the new invert setting
369   */
370  public void setInvertSelection(boolean invert) {
371
372    m_invert = invert;
373  }
374
375  /**
376   * Gets the attribute type to be deleted by the filter as a string.
377   *
378   * @return the attribute type as a String
379   */
380  protected String getAttributeTypeString() {
381
382    if (m_attTypeToDelete == Attribute.NOMINAL) return "nominal";
383    else if (m_attTypeToDelete == Attribute.NUMERIC) return "numeric";
384    else if (m_attTypeToDelete == Attribute.STRING) return "string";
385    else if (m_attTypeToDelete == Attribute.DATE) return "date";
386    else if (m_attTypeToDelete == Attribute.RELATIONAL) return "relational";
387    else return "unknown";
388  }
389
390  /**
391   * Sets the attribute type to be deleted by the filter.
392   *
393   * @param typeString a String representing the new type the filter should delete
394   */
395  protected void setAttributeTypeString(String typeString) {
396
397    typeString = typeString.toLowerCase();
398    if (typeString.equals("nominal")) m_attTypeToDelete = Attribute.NOMINAL;
399    else if (typeString.equals("numeric")) m_attTypeToDelete = Attribute.NUMERIC;
400    else if (typeString.equals("string")) m_attTypeToDelete = Attribute.STRING;
401    else if (typeString.equals("date")) m_attTypeToDelete = Attribute.DATE;
402    else if (typeString.equals("relational")) m_attTypeToDelete = Attribute.RELATIONAL;
403  }
404 
405  /**
406   * Returns the revision string.
407   *
408   * @return            the revision
409   */
410  public String getRevision() {
411    return RevisionUtils.extract("$Revision: 5987 $");
412  }
413
414  /**
415   * Main method for testing this class.
416   *
417   * @param argv should contain arguments to the filter: use -h for help
418   */
419  public static void main(String [] argv) {
420    runFilter(new RemoveType(), argv);
421  }
422}
Note: See TracBrowser for help on using the repository browser.