source: src/main/java/weka/experiment/LearningRateResultProducer.java @ 13

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

Import di weka.

File size: 28.1 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 *    LearningRateResultProducer.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23
24package weka.experiment;
25
26import weka.core.AdditionalMeasureProducer;
27import weka.core.Instances;
28import weka.core.Option;
29import weka.core.OptionHandler;
30import weka.core.RevisionHandler;
31import weka.core.RevisionUtils;
32import weka.core.Utils;
33
34import java.util.Enumeration;
35import java.util.Random;
36import java.util.Vector;
37
38/**
39 <!-- globalinfo-start -->
40 * Tells a sub-ResultProducer to reproduce the current run for varying sized subsamples of the dataset. Normally used with an AveragingResultProducer and CrossValidationResultProducer combo to generate learning curve results. For non-numeric result fields, the first value is used.
41 * <p/>
42 <!-- globalinfo-end -->
43 *
44 <!-- options-start -->
45 * Valid options are: <p/>
46 *
47 * <pre> -X &lt;num steps&gt;
48 *  The number of steps in the learning rate curve.
49 *  (default 10)</pre>
50 *
51 * <pre> -W &lt;class name&gt;
52 *  The full class name of a ResultProducer.
53 *  eg: weka.experiment.CrossValidationResultProducer</pre>
54 *
55 * <pre>
56 * Options specific to result producer weka.experiment.AveragingResultProducer:
57 * </pre>
58 *
59 * <pre> -F &lt;field name&gt;
60 *  The name of the field to average over.
61 *  (default "Fold")</pre>
62 *
63 * <pre> -X &lt;num results&gt;
64 *  The number of results expected per average.
65 *  (default 10)</pre>
66 *
67 * <pre> -S
68 *  Calculate standard deviations.
69 *  (default only averages)</pre>
70 *
71 * <pre> -W &lt;class name&gt;
72 *  The full class name of a ResultProducer.
73 *  eg: weka.experiment.CrossValidationResultProducer</pre>
74 *
75 * <pre>
76 * Options specific to result producer weka.experiment.CrossValidationResultProducer:
77 * </pre>
78 *
79 * <pre> -X &lt;number of folds&gt;
80 *  The number of folds to use for the cross-validation.
81 *  (default 10)</pre>
82 *
83 * <pre> -D
84 * Save raw split evaluator output.</pre>
85 *
86 * <pre> -O &lt;file/directory name/path&gt;
87 *  The filename where raw output will be stored.
88 *  If a directory name is specified then then individual
89 *  outputs will be gzipped, otherwise all output will be
90 *  zipped to the named file. Use in conjuction with -D. (default splitEvalutorOut.zip)</pre>
91 *
92 * <pre> -W &lt;class name&gt;
93 *  The full class name of a SplitEvaluator.
94 *  eg: weka.experiment.ClassifierSplitEvaluator</pre>
95 *
96 * <pre>
97 * Options specific to split evaluator weka.experiment.ClassifierSplitEvaluator:
98 * </pre>
99 *
100 * <pre> -W &lt;class name&gt;
101 *  The full class name of the classifier.
102 *  eg: weka.classifiers.bayes.NaiveBayes</pre>
103 *
104 * <pre> -C &lt;index&gt;
105 *  The index of the class for which IR statistics
106 *  are to be output. (default 1)</pre>
107 *
108 * <pre> -I &lt;index&gt;
109 *  The index of an attribute to output in the
110 *  results. This attribute should identify an
111 *  instance in order to know which instances are
112 *  in the test set of a cross validation. if 0
113 *  no output (default 0).</pre>
114 *
115 * <pre> -P
116 *  Add target and prediction columns to the result
117 *  for each fold.</pre>
118 *
119 * <pre>
120 * Options specific to classifier weka.classifiers.rules.ZeroR:
121 * </pre>
122 *
123 * <pre> -D
124 *  If set, classifier is run in debug mode and
125 *  may output additional info to the console</pre>
126 *
127 <!-- options-end -->
128 *
129 * All options after -- will be passed to the result producer.
130 *
131 * @author Len Trigg (trigg@cs.waikato.ac.nz)
132 * @version $Revision: 5597 $
133 */
134public class LearningRateResultProducer 
135  implements ResultListener, ResultProducer, OptionHandler,
136             AdditionalMeasureProducer, RevisionHandler {
137
138  /** for serialization */
139  static final long serialVersionUID = -3841159673490861331L;
140 
141  /** The dataset of interest */
142  protected Instances m_Instances;
143
144  /** The ResultListener to send results to */
145  protected ResultListener m_ResultListener = new CSVResultListener();
146
147  /** The ResultProducer used to generate results */
148  protected ResultProducer m_ResultProducer
149    = new AveragingResultProducer();
150
151  /** The names of any additional measures to look for in SplitEvaluators */
152  protected String [] m_AdditionalMeasures = null;
153
154  /**
155   * The minimum number of instances to use. If this is zero, the first
156   * step will contain m_StepSize instances
157   */
158  protected int m_LowerSize = 0;
159 
160  /**
161   * The maximum number of instances to use. -1 indicates no maximum
162   * (other than the total number of instances)
163   */
164  protected int m_UpperSize = -1;
165
166  /** The number of instances to add at each step */
167  protected int m_StepSize = 10;
168
169  /** The current dataset size during stepping */
170  protected int m_CurrentSize = 0;
171
172  /** The name of the key field containing the learning rate step number */
173  public static String STEP_FIELD_NAME = "Total_instances";
174
175  /**
176   * Returns a string describing this result producer
177   * @return a description of the result producer suitable for
178   * displaying in the explorer/experimenter gui
179   */
180  public String globalInfo() {
181    return "Tells a sub-ResultProducer to reproduce the current run for "
182      +"varying sized subsamples of the dataset. Normally used with "
183      +"an AveragingResultProducer and CrossValidationResultProducer "
184      +"combo to generate learning curve results. For non-numeric "
185      +"result fields, the first value is used.";
186  }
187
188
189  /**
190   * Determines if there are any constraints (imposed by the
191   * destination) on the result columns to be produced by
192   * resultProducers. Null should be returned if there are NO
193   * constraints, otherwise a list of column names should be
194   * returned as an array of Strings.
195   * @param rp the ResultProducer to which the constraints will apply
196   * @return an array of column names to which resutltProducer's
197   * results will be restricted.
198   * @throws Exception if constraints can't be determined
199   */
200  public String [] determineColumnConstraints(ResultProducer rp) 
201    throws Exception {
202    return null;
203  }
204
205  /**
206   * Gets the keys for a specified run number. Different run
207   * numbers correspond to different randomizations of the data. Keys
208   * produced should be sent to the current ResultListener
209   *
210   * @param run the run number to get keys for.
211   * @throws Exception if a problem occurs while getting the keys
212   */
213  public void doRunKeys(int run) throws Exception {
214
215    if (m_ResultProducer == null) {
216      throw new Exception("No ResultProducer set");
217    }
218    if (m_ResultListener == null) {
219      throw new Exception("No ResultListener set");
220    }
221    if (m_Instances == null) {
222      throw new Exception("No Instances set");
223    }
224
225    // Tell the resultproducer to send results to us
226    m_ResultProducer.setResultListener(this);
227    m_ResultProducer.setInstances(m_Instances);
228
229    // For each subsample size
230    if (m_LowerSize == 0) {
231      m_CurrentSize = m_StepSize;
232    } else {
233      m_CurrentSize = m_LowerSize;
234    }
235    while (m_CurrentSize <= m_Instances.numInstances() &&
236           ((m_UpperSize == -1) ||
237            (m_CurrentSize <= m_UpperSize))) {
238      m_ResultProducer.doRunKeys(run);
239      m_CurrentSize += m_StepSize;
240    }
241  }
242
243
244  /**
245   * Gets the results for a specified run number. Different run
246   * numbers correspond to different randomizations of the data. Results
247   * produced should be sent to the current ResultListener
248   *
249   * @param run the run number to get results for.
250   * @throws Exception if a problem occurs while getting the results
251   */
252  public void doRun(int run) throws Exception {
253
254    if (m_ResultProducer == null) {
255      throw new Exception("No ResultProducer set");
256    }
257    if (m_ResultListener == null) {
258      throw new Exception("No ResultListener set");
259    }
260    if (m_Instances == null) {
261      throw new Exception("No Instances set");
262    }
263
264    // Randomize on a copy of the original dataset
265    Instances runInstances = new Instances(m_Instances);
266    runInstances.randomize(new Random(run));
267   
268    /*if (runInstances.classAttribute().isNominal() && (m_Instances.numInstances() / m_StepSize >= 1)) {
269//      runInstances.stratify(m_Instances.numInstances() / m_StepSize);
270    }*/
271
272    // Tell the resultproducer to send results to us
273    m_ResultProducer.setResultListener(this);
274
275    // For each subsample size
276    if (m_LowerSize == 0) {
277      m_CurrentSize = m_StepSize;
278    } else {
279      m_CurrentSize = m_LowerSize;
280    }
281    while (m_CurrentSize <= m_Instances.numInstances() &&
282           ((m_UpperSize == -1) ||
283            (m_CurrentSize <= m_UpperSize))) {
284      m_ResultProducer.setInstances(new Instances(runInstances, 0, 
285                                                  m_CurrentSize));
286      m_ResultProducer.doRun(run);
287      m_CurrentSize += m_StepSize;
288    }
289  }
290
291 
292 
293  /**
294   * Prepare for the results to be received.
295   *
296   * @param rp the ResultProducer that will generate the results
297   * @throws Exception if an error occurs during preprocessing.
298   */
299  public void preProcess(ResultProducer rp) throws Exception {
300
301    if (m_ResultListener == null) {
302      throw new Exception("No ResultListener set");
303    }
304    m_ResultListener.preProcess(this);
305  }
306
307  /**
308   * Prepare to generate results. The ResultProducer should call
309   * preProcess(this) on the ResultListener it is to send results to.
310   *
311   * @throws Exception if an error occurs during preprocessing.
312   */
313  public void preProcess() throws Exception {
314   
315    if (m_ResultProducer == null) {
316      throw new Exception("No ResultProducer set");
317    }
318    // Tell the resultproducer to send results to us
319    m_ResultProducer.setResultListener(this);
320    m_ResultProducer.preProcess();
321  }
322 
323  /**
324   * When this method is called, it indicates that no more results
325   * will be sent that need to be grouped together in any way.
326   *
327   * @param rp the ResultProducer that generated the results
328   * @throws Exception if an error occurs
329   */
330  public void postProcess(ResultProducer rp) throws Exception {
331
332    m_ResultListener.postProcess(this);
333  }
334
335  /**
336   * When this method is called, it indicates that no more requests to
337   * generate results for the current experiment will be sent. The
338   * ResultProducer should call preProcess(this) on the
339   * ResultListener it is to send results to.
340   *
341   * @throws Exception if an error occurs
342   */
343  public void postProcess() throws Exception {
344
345    m_ResultProducer.postProcess();
346  }
347 
348  /**
349   * Accepts results from a ResultProducer.
350   *
351   * @param rp the ResultProducer that generated the results
352   * @param key an array of Objects (Strings or Doubles) that uniquely
353   * identify a result for a given ResultProducer with given compatibilityState
354   * @param result the results stored in an array. The objects stored in
355   * the array may be Strings, Doubles, or null (for the missing value).
356   * @throws Exception if the result could not be accepted.
357   */
358  public void acceptResult(ResultProducer rp, Object [] key, Object [] result)
359    throws Exception {
360
361    if (m_ResultProducer != rp) {
362      throw new Error("Unrecognized ResultProducer sending results!!");
363    }
364    // Add in current step as key field
365    Object [] newKey = new Object [key.length + 1];
366    System.arraycopy(key, 0, newKey, 0, key.length);
367    newKey[key.length] = new String("" + m_CurrentSize);
368    // Pass on to result listener
369    m_ResultListener.acceptResult(this, newKey, result);
370  }
371
372  /**
373   * Determines whether the results for a specified key must be
374   * generated.
375   *
376   * @param rp the ResultProducer wanting to generate the results
377   * @param key an array of Objects (Strings or Doubles) that uniquely
378   * identify a result for a given ResultProducer with given compatibilityState
379   * @return true if the result should be generated
380   * @throws Exception if it could not be determined if the result
381   * is needed.
382   */
383  public boolean isResultRequired(ResultProducer rp, Object [] key) 
384    throws Exception {
385
386    if (m_ResultProducer != rp) {
387      throw new Error("Unrecognized ResultProducer sending results!!");
388    }
389    // Add in current step as key field
390    Object [] newKey = new Object [key.length + 1];
391    System.arraycopy(key, 0, newKey, 0, key.length);
392    newKey[key.length] = new String("" + m_CurrentSize);
393    // Pass on request to result listener
394    return m_ResultListener.isResultRequired(this, newKey);
395  }
396
397  /**
398   * Gets the names of each of the columns produced for a single run.
399   *
400   * @return an array containing the name of each column
401   * @throws Exception if key names cannot be generated
402   */
403  public String [] getKeyNames() throws Exception {
404
405    String [] keyNames = m_ResultProducer.getKeyNames();
406    String [] newKeyNames = new String [keyNames.length + 1];
407    System.arraycopy(keyNames, 0, newKeyNames, 0, keyNames.length);
408    // Think of a better name for this key field
409    newKeyNames[keyNames.length] = STEP_FIELD_NAME;
410    return newKeyNames;
411  }
412
413  /**
414   * Gets the data types of each of the columns produced for a single run.
415   * This method should really be static.
416   *
417   * @return an array containing objects of the type of each column. The
418   * objects should be Strings, or Doubles.
419   * @throws Exception if the key types could not be determined (perhaps
420   * because of a problem from a nested sub-resultproducer)
421   */
422  public Object [] getKeyTypes() throws Exception {
423
424    Object [] keyTypes = m_ResultProducer.getKeyTypes();
425    Object [] newKeyTypes = new Object [keyTypes.length + 1];
426    System.arraycopy(keyTypes, 0, newKeyTypes, 0, keyTypes.length);
427    newKeyTypes[keyTypes.length] = "";
428    return newKeyTypes;
429  }
430
431  /**
432   * Gets the names of each of the columns produced for a single run.
433   * A new result field is added for the number of results used to
434   * produce each average.
435   * If only averages are being produced the names are not altered, if
436   * standard deviations are produced then "Dev_" and "Avg_" are prepended
437   * to each result deviation and average field respectively.
438   *
439   * @return an array containing the name of each column
440   * @throws Exception if the result names could not be determined (perhaps
441   * because of a problem from a nested sub-resultproducer)
442   */
443  public String [] getResultNames() throws Exception {
444
445    return m_ResultProducer.getResultNames();
446  }
447
448  /**
449   * Gets the data types of each of the columns produced for a single run.
450   *
451   * @return an array containing objects of the type of each column. The
452   * objects should be Strings, or Doubles.
453   * @throws Exception if the result types could not be determined (perhaps
454   * because of a problem from a nested sub-resultproducer)
455   */
456  public Object [] getResultTypes() throws Exception {
457
458    return m_ResultProducer.getResultTypes();
459  }
460
461  /**
462   * Gets a description of the internal settings of the result
463   * producer, sufficient for distinguishing a ResultProducer
464   * instance from another with different settings (ignoring
465   * those settings set through this interface). For example,
466   * a cross-validation ResultProducer may have a setting for the
467   * number of folds. For a given state, the results produced should
468   * be compatible. Typically if a ResultProducer is an OptionHandler,
469   * this string will represent the command line arguments required
470   * to set the ResultProducer to that state.
471   *
472   * @return the description of the ResultProducer state, or null
473   * if no state is defined
474   */
475  public String getCompatibilityState() {
476
477    String result = " ";
478    // + "-F " + Utils.quote(getKeyFieldName())
479    // + " -X " + getStepSize() + " ";
480    if (m_ResultProducer == null) {
481      result += "<null ResultProducer>";
482    } else {
483      result += "-W " + m_ResultProducer.getClass().getName();
484    }
485    result  += " -- " + m_ResultProducer.getCompatibilityState();
486    return result.trim();
487  }
488
489
490  /**
491   * Returns an enumeration describing the available options..
492   *
493   * @return an enumeration of all the available options.
494   */
495  public Enumeration listOptions() {
496
497    Vector newVector = new Vector(2);
498
499    newVector.addElement(new Option(
500             "\tThe number of steps in the learning rate curve.\n"
501              +"\t(default 10)", 
502             "X", 1, 
503             "-X <num steps>"));
504    newVector.addElement(new Option(
505             "\tThe full class name of a ResultProducer.\n"
506              +"\teg: weka.experiment.CrossValidationResultProducer", 
507             "W", 1, 
508             "-W <class name>"));
509
510    if ((m_ResultProducer != null) &&
511        (m_ResultProducer instanceof OptionHandler)) {
512      newVector.addElement(new Option(
513             "",
514             "", 0, "\nOptions specific to result producer "
515             + m_ResultProducer.getClass().getName() + ":"));
516      Enumeration enu = ((OptionHandler)m_ResultProducer).listOptions();
517      while (enu.hasMoreElements()) {
518        newVector.addElement(enu.nextElement());
519      }
520    }
521    return newVector.elements();
522  }
523
524  /**
525   * Parses a given list of options. <p/>
526   *
527   <!-- options-start -->
528   * Valid options are: <p/>
529   *
530   * <pre> -X &lt;num steps&gt;
531   *  The number of steps in the learning rate curve.
532   *  (default 10)</pre>
533   *
534   * <pre> -W &lt;class name&gt;
535   *  The full class name of a ResultProducer.
536   *  eg: weka.experiment.CrossValidationResultProducer</pre>
537   *
538   * <pre>
539   * Options specific to result producer weka.experiment.AveragingResultProducer:
540   * </pre>
541   *
542   * <pre> -F &lt;field name&gt;
543   *  The name of the field to average over.
544   *  (default "Fold")</pre>
545   *
546   * <pre> -X &lt;num results&gt;
547   *  The number of results expected per average.
548   *  (default 10)</pre>
549   *
550   * <pre> -S
551   *  Calculate standard deviations.
552   *  (default only averages)</pre>
553   *
554   * <pre> -W &lt;class name&gt;
555   *  The full class name of a ResultProducer.
556   *  eg: weka.experiment.CrossValidationResultProducer</pre>
557   *
558   * <pre>
559   * Options specific to result producer weka.experiment.CrossValidationResultProducer:
560   * </pre>
561   *
562   * <pre> -X &lt;number of folds&gt;
563   *  The number of folds to use for the cross-validation.
564   *  (default 10)</pre>
565   *
566   * <pre> -D
567   * Save raw split evaluator output.</pre>
568   *
569   * <pre> -O &lt;file/directory name/path&gt;
570   *  The filename where raw output will be stored.
571   *  If a directory name is specified then then individual
572   *  outputs will be gzipped, otherwise all output will be
573   *  zipped to the named file. Use in conjuction with -D. (default splitEvalutorOut.zip)</pre>
574   *
575   * <pre> -W &lt;class name&gt;
576   *  The full class name of a SplitEvaluator.
577   *  eg: weka.experiment.ClassifierSplitEvaluator</pre>
578   *
579   * <pre>
580   * Options specific to split evaluator weka.experiment.ClassifierSplitEvaluator:
581   * </pre>
582   *
583   * <pre> -W &lt;class name&gt;
584   *  The full class name of the classifier.
585   *  eg: weka.classifiers.bayes.NaiveBayes</pre>
586   *
587   * <pre> -C &lt;index&gt;
588   *  The index of the class for which IR statistics
589   *  are to be output. (default 1)</pre>
590   *
591   * <pre> -I &lt;index&gt;
592   *  The index of an attribute to output in the
593   *  results. This attribute should identify an
594   *  instance in order to know which instances are
595   *  in the test set of a cross validation. if 0
596   *  no output (default 0).</pre>
597   *
598   * <pre> -P
599   *  Add target and prediction columns to the result
600   *  for each fold.</pre>
601   *
602   * <pre>
603   * Options specific to classifier weka.classifiers.rules.ZeroR:
604   * </pre>
605   *
606   * <pre> -D
607   *  If set, classifier is run in debug mode and
608   *  may output additional info to the console</pre>
609   *
610   <!-- options-end -->
611   *
612   * All options after -- will be passed to the result producer.
613   *
614   * @param options the list of options as an array of strings
615   * @throws Exception if an option is not supported
616   */
617  public void setOptions(String[] options) throws Exception {
618   
619    String stepSize = Utils.getOption('S', options);
620    if (stepSize.length() != 0) {
621      setStepSize(Integer.parseInt(stepSize));
622    } else {
623      setStepSize(10);
624    }
625
626    String lowerSize = Utils.getOption('L', options);
627    if (lowerSize.length() != 0) {
628      setLowerSize(Integer.parseInt(lowerSize));
629    } else {
630      setLowerSize(0);
631    }
632   
633    String upperSize = Utils.getOption('U', options);
634    if (upperSize.length() != 0) {
635      setUpperSize(Integer.parseInt(upperSize));
636    } else {
637      setUpperSize(-1);
638    }
639
640    String rpName = Utils.getOption('W', options);
641    if (rpName.length() == 0) {
642      throw new Exception("A ResultProducer must be specified with"
643                          + " the -W option.");
644    }
645    // Do it first without options, so if an exception is thrown during
646    // the option setting, listOptions will contain options for the actual
647    // RP.
648    setResultProducer((ResultProducer)Utils.forName(
649                      ResultProducer.class,
650                      rpName,
651                      null));
652    if (getResultProducer() instanceof OptionHandler) {
653      ((OptionHandler) getResultProducer())
654        .setOptions(Utils.partitionOptions(options));
655    }
656  }
657
658  /**
659   * Gets the current settings of the result producer.
660   *
661   * @return an array of strings suitable for passing to setOptions
662   */
663  public String [] getOptions() {
664
665    String [] seOptions = new String [0];
666    if ((m_ResultProducer != null) && 
667        (m_ResultProducer instanceof OptionHandler)) {
668      seOptions = ((OptionHandler)m_ResultProducer).getOptions();
669    }
670   
671    String [] options = new String [seOptions.length + 9];
672    int current = 0;
673
674    options[current++] = "-S";
675    options[current++] = "" + getStepSize();
676    options[current++] = "-L";
677    options[current++] = "" + getLowerSize();
678    options[current++] = "-U";
679    options[current++] = "" + getUpperSize();
680    if (getResultProducer() != null) {
681      options[current++] = "-W";
682      options[current++] = getResultProducer().getClass().getName();
683    }
684    options[current++] = "--";
685
686    System.arraycopy(seOptions, 0, options, current, 
687                     seOptions.length);
688    current += seOptions.length;
689    while (current < options.length) {
690      options[current++] = "";
691    }
692    return options;
693  }
694
695  /**
696   * Set a list of method names for additional measures to look for
697   * in SplitEvaluators. This could contain many measures (of which only a
698   * subset may be produceable by the current resultProducer) if an experiment
699   * is the type that iterates over a set of properties.
700   * @param additionalMeasures an array of measure names, null if none
701   */
702  public void setAdditionalMeasures(String [] additionalMeasures) {
703    m_AdditionalMeasures = additionalMeasures;
704
705    if (m_ResultProducer != null) {
706      System.err.println("LearningRateResultProducer: setting additional "
707                         +"measures for "
708                         +"ResultProducer");
709      m_ResultProducer.setAdditionalMeasures(m_AdditionalMeasures);
710    }
711  }
712
713  /**
714   * Returns an enumeration of any additional measure names that might be
715   * in the result producer
716   * @return an enumeration of the measure names
717   */
718  public Enumeration enumerateMeasures() {
719    Vector newVector = new Vector();
720    if (m_ResultProducer instanceof AdditionalMeasureProducer) {
721      Enumeration en = ((AdditionalMeasureProducer)m_ResultProducer).
722        enumerateMeasures();
723      while (en.hasMoreElements()) {
724        String mname = (String)en.nextElement();
725        newVector.addElement(mname);
726      }
727    }
728    return newVector.elements();
729  }
730
731  /**
732   * Returns the value of the named measure
733   * @param additionalMeasureName the name of the measure to query for its value
734   * @return the value of the named measure
735   * @throws IllegalArgumentException if the named measure is not supported
736   */
737  public double getMeasure(String additionalMeasureName) {
738    if (m_ResultProducer instanceof AdditionalMeasureProducer) {
739      return ((AdditionalMeasureProducer)m_ResultProducer).
740        getMeasure(additionalMeasureName);
741    } else {
742      throw new IllegalArgumentException("LearningRateResultProducer: "
743                          +"Can't return value for : "+additionalMeasureName
744                          +". "+m_ResultProducer.getClass().getName()+" "
745                          +"is not an AdditionalMeasureProducer");
746    }
747  }
748
749  /**
750   * Sets the dataset that results will be obtained for.
751   *
752   * @param instances a value of type 'Instances'.
753   */
754  public void setInstances(Instances instances) {
755   
756    m_Instances = instances;
757  }
758
759
760  /**
761   * Returns the tip text for this property
762   * @return tip text for this property suitable for
763   * displaying in the explorer/experimenter gui
764   */
765  public String lowerSizeTipText() {
766    return "Set the minmum number of instances in a dataset. Setting zero "
767      + "here will actually use <stepSize> number of instances at the first "
768      + "step (since it makes no sense to use zero instances :-))";
769  }
770
771  /**
772   * Get the value of LowerSize.
773   *
774   * @return Value of LowerSize.
775   */
776  public int getLowerSize() {
777   
778    return m_LowerSize;
779  }
780 
781  /**
782   * Set the value of LowerSize.
783   *
784   * @param newLowerSize Value to assign to
785   * LowerSize.
786   */
787  public void setLowerSize(int newLowerSize) {
788   
789    m_LowerSize = newLowerSize;
790  }
791
792  /**
793   * Returns the tip text for this property
794   * @return tip text for this property suitable for
795   * displaying in the explorer/experimenter gui
796   */
797  public String upperSizeTipText() {
798    return "Set the maximum number of instances in a dataset. Setting -1 "
799      + "sets no upper limit (other than the total number of instances "
800      + "in the full dataset)";
801  }
802
803  /**
804   * Get the value of UpperSize.
805   *
806   * @return Value of UpperSize.
807   */
808  public int getUpperSize() {
809   
810    return m_UpperSize;
811  }
812 
813  /**
814   * Set the value of UpperSize.
815   *
816   * @param newUpperSize Value to assign to
817   * UpperSize.
818   */
819  public void setUpperSize(int newUpperSize) {
820   
821    m_UpperSize = newUpperSize;
822  }
823
824
825  /**
826   * Returns the tip text for this property
827   * @return tip text for this property suitable for
828   * displaying in the explorer/experimenter gui
829   */
830  public String stepSizeTipText() {
831    return "Set the number of instances to add at each step.";
832  }
833
834  /**
835   * Get the value of StepSize.
836   *
837   * @return Value of StepSize.
838   */
839  public int getStepSize() {
840   
841    return m_StepSize;
842  }
843 
844  /**
845   * Set the value of StepSize.
846   *
847   * @param newStepSize Value to assign to
848   * StepSize.
849   */
850  public void setStepSize(int newStepSize) {
851   
852    m_StepSize = newStepSize;
853  }
854
855  /**
856   * Sets the object to send results of each run to.
857   *
858   * @param listener a value of type 'ResultListener'
859   */
860  public void setResultListener(ResultListener listener) {
861
862    m_ResultListener = listener;
863  }
864 
865  /**
866   * Returns the tip text for this property
867   * @return tip text for this property suitable for
868   * displaying in the explorer/experimenter gui
869   */
870  public String resultProducerTipText() {
871    return "Set the resultProducer for which learning rate results should be "
872      + "generated.";
873  }
874
875  /**
876   * Get the ResultProducer.
877   *
878   * @return the ResultProducer.
879   */
880  public ResultProducer getResultProducer() {
881   
882    return m_ResultProducer;
883  }
884 
885  /**
886   * Set the ResultProducer.
887   *
888   * @param newResultProducer new ResultProducer to use.
889   */
890  public void setResultProducer(ResultProducer newResultProducer) {
891
892    m_ResultProducer = newResultProducer;
893    m_ResultProducer.setResultListener(this);
894  }
895
896  /**
897   * Gets a text descrption of the result producer.
898   *
899   * @return a text description of the result producer.
900   */
901  public String toString() {
902
903    String result = "LearningRateResultProducer: ";
904    result += getCompatibilityState();
905    if (m_Instances == null) {
906      result += ": <null Instances>";
907    } else {
908      result += ": " + Utils.backQuoteChars(m_Instances.relationName());
909    }
910    return result;
911  }
912
913  /**
914   * Returns the revision string.
915   *
916   * @return            the revision
917   */
918  public String getRevision() {
919    return RevisionUtils.extract("$Revision: 5597 $");
920  }
921} // LearningRateResultProducer
Note: See TracBrowser for help on using the repository browser.