source: src/main/java/weka/classifiers/functions/PLSClassifier.java @ 17

Last change on this file since 17 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 10.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 * PLSClassifier.java
19 * Copyright (C) 2006 University of Waikato, Hamilton, New Zealand
20 */
21
22package weka.classifiers.functions;
23
24import weka.classifiers.Classifier;
25import weka.classifiers.AbstractClassifier;
26import weka.core.Capabilities;
27import weka.core.Instance;
28import weka.core.Instances;
29import weka.core.Option;
30import weka.core.OptionHandler;
31import weka.core.RevisionUtils;
32import weka.core.Utils;
33import weka.core.Capabilities.Capability;
34import weka.filters.Filter;
35import weka.filters.supervised.attribute.PLSFilter;
36
37import java.util.Enumeration;
38import java.util.Vector;
39
40/**
41 <!-- globalinfo-start -->
42 * A wrapper classifier for the PLSFilter, utilizing the PLSFilter's ability to perform predictions.
43 * <p/>
44 <!-- globalinfo-end -->
45 *
46 <!-- options-start -->
47 * Valid options are: <p/>
48 *
49 * <pre> -filter &lt;filter specification&gt;
50 *  The PLS filter to use. Full classname of filter to include,  followed by scheme options.
51 *  (default: weka.filters.supervised.attribute.PLSFilter)</pre>
52 *
53 * <pre> -D
54 *  If set, classifier is run in debug mode and
55 *  may output additional info to the console</pre>
56 *
57 * <pre>
58 * Options specific to filter weka.filters.supervised.attribute.PLSFilter ('-filter'):
59 * </pre>
60 *
61 * <pre> -D
62 *  Turns on output of debugging information.</pre>
63 *
64 * <pre> -C &lt;num&gt;
65 *  The number of components to compute.
66 *  (default: 20)</pre>
67 *
68 * <pre> -U
69 *  Updates the class attribute as well.
70 *  (default: off)</pre>
71 *
72 * <pre> -M
73 *  Turns replacing of missing values on.
74 *  (default: off)</pre>
75 *
76 * <pre> -A &lt;SIMPLS|PLS1&gt;
77 *  The algorithm to use.
78 *  (default: PLS1)</pre>
79 *
80 * <pre> -P &lt;none|center|standardize&gt;
81 *  The type of preprocessing that is applied to the data.
82 *  (default: center)</pre>
83 *
84 <!-- options-end -->
85 *
86 * @author  fracpete (fracpete at waikato dot ac dot nz)
87 * @version $Revision: 5987 $
88 */
89public class PLSClassifier
90  extends AbstractClassifier {
91 
92  /** for serialization */
93  private static final long serialVersionUID = 4819775160590973256L;
94
95  /** the PLS filter */
96  protected PLSFilter m_Filter = new PLSFilter();
97
98  /** the actual filter to use */
99  protected PLSFilter m_ActualFilter = null;
100 
101  /**
102   * Returns a string describing classifier
103   *
104   * @return a description suitable for displaying in the
105   *         explorer/experimenter gui
106   */
107  public String globalInfo() {
108    return 
109        "A wrapper classifier for the PLSFilter, utilizing the PLSFilter's "
110      + "ability to perform predictions.";
111  }
112
113  /**
114   * Gets an enumeration describing the available options.
115   *
116   * @return an enumeration of all the available options.
117   */
118  public Enumeration listOptions(){
119    Vector              result;
120    Enumeration         en;
121
122    result = new Vector();
123
124    result.addElement(new Option(
125        "\tThe PLS filter to use. Full classname of filter to include, "
126        + "\tfollowed by scheme options.\n"
127        + "\t(default: weka.filters.supervised.attribute.PLSFilter)",
128        "filter", 1, "-filter <filter specification>"));
129
130    en = super.listOptions();
131    while (en.hasMoreElements())
132      result.addElement(en.nextElement());
133
134    if (getFilter() instanceof OptionHandler) {
135      result.addElement(new Option(
136          "",
137          "", 0, "\nOptions specific to filter "
138          + getFilter().getClass().getName() + " ('-filter'):"));
139     
140      en = ((OptionHandler) getFilter()).listOptions();
141      while (en.hasMoreElements())
142        result.addElement(en.nextElement());
143    }
144
145    return result.elements();
146  }
147 
148  /**
149   * returns the options of the current setup
150   *
151   * @return            the current options
152   */
153  public String[] getOptions(){
154    int         i;
155    Vector      result;
156    String[]    options;
157
158    result = new Vector();
159
160    result.add("-filter");
161    if (getFilter() instanceof OptionHandler)
162      result.add(
163            getFilter().getClass().getName() 
164          + " " 
165          + Utils.joinOptions(((OptionHandler) getFilter()).getOptions()));
166    else
167      result.add(
168          getFilter().getClass().getName());
169
170    options = super.getOptions();
171    for (i = 0; i < options.length; i++)
172      result.add(options[i]);
173
174    return (String[]) result.toArray(new String[result.size()]);         
175  }
176
177  /**
178   * Parses the options for this object. <p/>
179   *
180   <!-- options-start -->
181   * Valid options are: <p/>
182   *
183   * <pre> -filter &lt;filter specification&gt;
184   *  The PLS filter to use. Full classname of filter to include,  followed by scheme options.
185   *  (default: weka.filters.supervised.attribute.PLSFilter)</pre>
186   *
187   * <pre> -D
188   *  If set, classifier is run in debug mode and
189   *  may output additional info to the console</pre>
190   *
191   * <pre>
192   * Options specific to filter weka.filters.supervised.attribute.PLSFilter ('-filter'):
193   * </pre>
194   *
195   * <pre> -D
196   *  Turns on output of debugging information.</pre>
197   *
198   * <pre> -C &lt;num&gt;
199   *  The number of components to compute.
200   *  (default: 20)</pre>
201   *
202   * <pre> -U
203   *  Updates the class attribute as well.
204   *  (default: off)</pre>
205   *
206   * <pre> -M
207   *  Turns replacing of missing values on.
208   *  (default: off)</pre>
209   *
210   * <pre> -A &lt;SIMPLS|PLS1&gt;
211   *  The algorithm to use.
212   *  (default: PLS1)</pre>
213   *
214   * <pre> -P &lt;none|center|standardize&gt;
215   *  The type of preprocessing that is applied to the data.
216   *  (default: center)</pre>
217   *
218   <!-- options-end -->
219   *
220   * @param options     the options to use
221   * @throws Exception  if setting of options fails
222   */
223  public void setOptions(String[] options) throws Exception {
224    String      tmpStr;
225    String[]    tmpOptions;
226   
227    super.setOptions(options);
228   
229    tmpStr     = Utils.getOption("filter", options);
230    tmpOptions = Utils.splitOptions(tmpStr);
231    if (tmpOptions.length != 0) {
232      tmpStr        = tmpOptions[0];
233      tmpOptions[0] = "";
234      setFilter((Filter) Utils.forName(Filter.class, tmpStr, tmpOptions));
235    }
236  }
237 
238  /**
239   * Returns the tip text for this property
240   *
241   * @return            tip text for this property suitable for
242   *                    displaying in the explorer/experimenter gui
243   */
244  public String filterTipText() {
245    return "The PLS filter to be used (only used for setup).";
246  }
247
248  /**
249   * Set the PLS filter (only used for setup).
250   *
251   * @param value       the kernel filter.
252   * @throws Exception  if not PLSFilter
253   */
254  public void setFilter(Filter value) throws Exception {
255    if (!(value instanceof PLSFilter))
256      throw new Exception("Filter has to be PLSFilter!");
257    else
258      m_Filter = (PLSFilter) value;
259  }
260
261  /**
262   * Get the PLS filter.
263   *
264   * @return            the PLS filter
265   */
266  public Filter getFilter() {
267    return m_Filter;
268  }
269 
270  /**
271   * Returns default capabilities of the classifier.
272   *
273   * @return            the capabilities of this classifier
274   */
275  public Capabilities getCapabilities() {
276    Capabilities result = getFilter().getCapabilities();
277
278    // class
279    result.enable(Capability.MISSING_CLASS_VALUES);
280
281    // other
282    result.setMinimumNumberInstances(1);
283   
284    return result;
285  }
286
287  /**
288   * builds the classifier
289   *
290   * @param data        the training instances
291   * @throws Exception  if something goes wrong
292   */
293  public void buildClassifier(Instances data) throws Exception {
294    // can classifier handle the data?
295    getCapabilities().testWithFail(data);
296
297    // remove instances with missing class
298    data = new Instances(data);
299    data.deleteWithMissingClass();
300   
301    // initialize filter
302    m_ActualFilter = (PLSFilter) Filter.makeCopy(m_Filter);
303    m_ActualFilter.setPerformPrediction(false);
304    m_ActualFilter.setInputFormat(data);
305    Filter.useFilter(data, m_ActualFilter);
306    m_ActualFilter.setPerformPrediction(true);
307  }
308
309  /**
310   * Classifies the given test instance. The instance has to belong to a
311   * dataset when it's being classified.
312   *
313   * @param instance    the instance to be classified
314   * @return            the predicted most likely class for the instance or
315   *                    Utils.missingValue() if no prediction is made
316   * @throws Exception  if an error occurred during the prediction
317   */
318  public double classifyInstance(Instance instance) throws Exception {
319    double      result;
320    Instance    pred;
321   
322    m_ActualFilter.input(instance);
323    m_ActualFilter.batchFinished();
324    pred   = m_ActualFilter.output();
325    result = pred.classValue();
326   
327    return result;
328  }
329
330  /**
331   * returns a string representation of the classifier
332   *
333   * @return            a string representation of the classifier
334   */
335  public String toString() {
336    String      result;
337   
338    result =   this.getClass().getName() + "\n" 
339             + this.getClass().getName().replaceAll(".", "=") + "\n\n";
340    result += "# Components..........: " + m_Filter.getNumComponents() + "\n";
341    result += "Algorithm.............: " + m_Filter.getAlgorithm().getSelectedTag().getReadable() + "\n";
342    result += "Replace missing values: " + (m_Filter.getReplaceMissing() ? "yes" : "no") + "\n";
343    result += "Preprocessing.........: " + m_Filter.getPreprocessing().getSelectedTag().getReadable() + "\n";
344   
345    return result;
346  }
347 
348  /**
349   * Returns the revision string.
350   *
351   * @return            the revision
352   */
353  public String getRevision() {
354    return RevisionUtils.extract("$Revision: 5987 $");
355  }
356 
357  /**
358   * Main method for running this classifier from commandline.
359   *
360   * @param args        the options
361   */
362  public static void main(String[] args) {
363    runClassifier(new PLSClassifier(), args);
364  }
365}
Note: See TracBrowser for help on using the repository browser.