source: branches/MetisMQI/src/main/java/weka/filters/unsupervised/attribute/TimeSeriesDelta.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: 6.8 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 *    TimeSeriesDelta.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23
24package weka.filters.unsupervised.attribute;
25
26import weka.core.Capabilities;
27import weka.core.Instance; 
28import weka.core.DenseInstance;
29import weka.core.Instances;
30import weka.core.RevisionUtils;
31import weka.core.SparseInstance;
32import weka.core.UnsupportedAttributeTypeException;
33import weka.core.Capabilities.Capability;
34import weka.core.Utils;
35
36
37/**
38 <!-- globalinfo-start -->
39 * An instance filter that assumes instances form time-series data and replaces attribute values in the current instance with the difference between the current value and the equivalent attribute attribute value of some previous (or future) instance. For instances where the time-shifted value is unknown either the instance may be dropped, or missing values used. Skips the class attribute if it is set.
40 * <p/>
41 <!-- globalinfo-end -->
42 *
43 <!-- options-start -->
44 * Valid options are: <p/>
45 *
46 * <pre> -R &lt;index1,index2-index4,...&gt;
47 *  Specify list of columns to translate in time. First and
48 *  last are valid indexes. (default none)</pre>
49 *
50 * <pre> -V
51 *  Invert matching sense (i.e. calculate for all non-specified columns)</pre>
52 *
53 * <pre> -I &lt;num&gt;
54 *  The number of instances forward to translate values
55 *  between. A negative number indicates taking values from
56 *  a past instance. (default -1)</pre>
57 *
58 * <pre> -M
59 *  For instances at the beginning or end of the dataset where
60 *  the translated values are not known, remove those instances
61 *  (default is to use missing values).</pre>
62 *
63 <!-- options-end -->
64 *
65 * @author Len Trigg (trigg@cs.waikato.ac.nz)
66 * @version $Revision: 5987 $
67 */
68public class TimeSeriesDelta 
69  extends TimeSeriesTranslate {
70 
71  /** for serialization */
72  static final long serialVersionUID = 3101490081896634942L;
73
74  /**
75   * Returns a string describing this classifier
76   * @return a description of the classifier suitable for
77   * displaying in the explorer/experimenter gui
78   */
79  public String globalInfo() {
80    return "An instance filter that assumes instances form time-series data and "
81      + "replaces attribute values in the current instance with the difference "
82      + "between the current value and the equivalent attribute attribute value "
83      + "of some previous (or future) instance. For instances where the time-shifted "
84      + "value is unknown either the instance may be dropped, or missing values "
85      + "used. Skips the class attribute if it is set.";
86  }
87
88  /**
89   * Returns the Capabilities of this filter.
90   *
91   * @return            the capabilities of this object
92   * @see               Capabilities
93   */
94  public Capabilities getCapabilities() {
95    Capabilities result = super.getCapabilities();
96    result.disableAll();
97
98    // attributes
99    result.enableAllAttributes();
100    result.enable(Capability.MISSING_VALUES);
101   
102    // class
103    result.enableAllClasses();
104    result.enable(Capability.MISSING_CLASS_VALUES);
105    result.enable(Capability.NO_CLASS);
106   
107    return result;
108  }
109
110  /**
111   * Sets the format of the input instances.
112   *
113   * @param instanceInfo an Instances object containing the input instance
114   * structure (any instances contained in the object are ignored - only the
115   * structure is required).
116   * @return true if the outputFormat may be collected immediately
117   * @throws UnsupportedAttributeTypeException if selected
118   * attributes are not numeric. 
119   */
120  public boolean setInputFormat(Instances instanceInfo) throws Exception {
121
122    if ((instanceInfo.classIndex() > 0) && (!getFillWithMissing())) {
123      throw new IllegalArgumentException("TimeSeriesDelta: Need to fill in missing values " +
124                                         "using appropriate option when class index is set.");
125    }
126    super.setInputFormat(instanceInfo);
127    // Create the output buffer
128    Instances outputFormat = new Instances(instanceInfo, 0); 
129    for(int i = 0; i < instanceInfo.numAttributes(); i++) {
130      if (i != instanceInfo.classIndex()) {
131        if (m_SelectedCols.isInRange(i)) {
132          if (outputFormat.attribute(i).isNumeric()) {
133            outputFormat.renameAttribute(i, outputFormat.attribute(i).name()
134                                         + " d"
135                                         + (m_InstanceRange < 0 ? '-' : '+')
136                                         + Math.abs(m_InstanceRange));
137          } else {
138            throw new UnsupportedAttributeTypeException("Time delta attributes must be numeric!");
139          }
140        }
141      }
142    }
143    outputFormat.setClassIndex(instanceInfo.classIndex());
144    setOutputFormat(outputFormat);
145    return true;
146  }
147 
148
149  /**
150   * Creates a new instance the same as one instance (the "destination")
151   * but with some attribute values copied from another instance
152   * (the "source")
153   *
154   * @param source the source instance
155   * @param dest the destination instance
156   * @return the new merged instance
157   */
158  protected Instance mergeInstances(Instance source, Instance dest) {
159
160    Instances outputFormat = outputFormatPeek();
161    double[] vals = new double[outputFormat.numAttributes()];
162    for(int i = 0; i < vals.length; i++) {
163      if ((i != outputFormat.classIndex()) && (m_SelectedCols.isInRange(i))) {
164        if ((source != null) && !source.isMissing(i) && !dest.isMissing(i)) {
165          vals[i] = dest.value(i) - source.value(i);
166        } else {
167          vals[i] = Utils.missingValue();
168        }
169      } else {
170        vals[i] = dest.value(i);
171      }
172    }
173    Instance inst = null;
174    if (dest instanceof SparseInstance) {
175      inst = new SparseInstance(dest.weight(), vals);
176    } else {
177      inst = new DenseInstance(dest.weight(), vals);
178    }
179    inst.setDataset(dest.dataset());
180    return inst;
181  }
182 
183  /**
184   * Returns the revision string.
185   *
186   * @return            the revision
187   */
188  public String getRevision() {
189    return RevisionUtils.extract("$Revision: 5987 $");
190  }
191 
192  /**
193   * Main method for testing this class.
194   *
195   * @param argv should contain arguments to the filter: use -h for help
196   */
197  public static void main(String [] argv) {
198    runFilter(new TimeSeriesDelta(), argv);
199  }
200}
Note: See TracBrowser for help on using the repository browser.