source: src/main/java/weka/classifiers/misc/FLR.java @ 27

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

Import di weka.

File size: 29.2 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 *    FLR.java
19 *    Copyright (C) 2002 Ioannis N. Athanasiadis
20 *
21 */
22
23package weka.classifiers.misc;
24
25import weka.classifiers.Classifier;
26import weka.classifiers.AbstractClassifier;
27import weka.core.AdditionalMeasureProducer;
28import weka.core.AttributeStats;
29import weka.core.Capabilities;
30import weka.core.Instance;
31import weka.core.Instances;
32import weka.core.Option;
33import weka.core.RevisionHandler;
34import weka.core.RevisionUtils;
35import weka.core.Summarizable;
36import weka.core.TechnicalInformation;
37import weka.core.TechnicalInformationHandler;
38import weka.core.Utils;
39import weka.core.Capabilities.Capability;
40import weka.core.TechnicalInformation.Field;
41import weka.core.TechnicalInformation.Type;
42
43import java.io.BufferedReader;
44import java.io.File;
45import java.io.FileReader;
46import java.io.Serializable;
47import java.util.Enumeration;
48import java.util.Vector;
49
50/**
51 <!-- globalinfo-start -->
52 * Fuzzy Lattice Reasoning Classifier (FLR) v5.0<br/>
53 * <br/>
54 * The Fuzzy Lattice Reasoning Classifier uses the notion of Fuzzy Lattices for creating a Reasoning Environment.<br/>
55 * The current version can be used for classification using numeric predictors.<br/>
56 * <br/>
57 * For more information see:<br/>
58 * <br/>
59 * I. N. Athanasiadis, V. G. Kaburlasos, P. A. Mitkas, V. Petridis: Applying Machine Learning Techniques on Air Quality Data for Real-Time Decision Support. In: 1st Intl. NAISO Symposium on Information Technologies in Environmental Engineering (ITEE-2003), Gdansk, Poland, 2003.<br/>
60 * <br/>
61 * V. G. Kaburlasos, I. N. Athanasiadis, P. A. Mitkas, V. Petridis (2003). Fuzzy Lattice Reasoning (FLR) Classifier and its Application on Improved Estimation of Ambient Ozone Concentration.
62 * <p/>
63 <!-- globalinfo-end -->
64 *
65 <!-- technical-bibtex-start -->
66 * BibTeX:
67 * <pre>
68 * &#64;inproceedings{Athanasiadis2003,
69 *    address = {Gdansk, Poland},
70 *    author = {I. N. Athanasiadis and V. G. Kaburlasos and P. A. Mitkas and V. Petridis},
71 *    booktitle = {1st Intl. NAISO Symposium on Information Technologies in Environmental Engineering (ITEE-2003)},
72 *    note = {Abstract in ICSC-NAISO Academic Press, Canada (ISBN:3906454339), pg.51},
73 *    publisher = {ICSC-NAISO Academic Press},
74 *    title = {Applying Machine Learning Techniques on Air Quality Data for Real-Time Decision Support},
75 *    year = {2003}
76 * }
77 *
78 * &#64;unpublished{Kaburlasos2003,
79 *    author = {V. G. Kaburlasos and I. N. Athanasiadis and P. A. Mitkas and V. Petridis},
80 *    title = {Fuzzy Lattice Reasoning (FLR) Classifier and its Application on Improved Estimation of Ambient Ozone Concentration},
81 *    year = {2003}
82 * }
83 * </pre>
84 * <p/>
85 <!-- technical-bibtex-end -->
86 *
87 <!-- options-start -->
88 * Valid options are: <p/>
89 *
90 * <pre> -R
91 *  Set vigilance parameter rhoa.
92 *  (a float in range [0,1])</pre>
93 *
94 * <pre> -B
95 *  Set boundaries File
96 *  Note:  The boundaries file is a simple text file containing
97 *  a row with a Fuzzy Lattice defining the metric space.
98 *  For example, the boundaries file could contain the following
99 *  the metric space for the iris dataset:
100 *  [ 4.3  7.9 ]  [ 2.0  4.4 ]  [ 1.0  6.9 ]  [ 0.1  2.5 ]  in Class:  -1
101 *  This lattice just contains the min and max value in each
102 *  dimension.
103 *  In other kind of problems this may not be just a min-max
104 *  operation, but it could contain limits defined by the problem
105 *  itself.
106 *  Thus, this option should be set by the user.
107 *  If ommited, the metric space used contains the mins and maxs
108 *  of the training split.</pre>
109 *
110 * <pre> -Y
111 *  Show Rules</pre>
112 *
113 <!-- options-end -->
114 *
115 * For further information contact I.N.Athanasiadis (ionathan@iti.gr)
116 *
117 * @author Ioannis N. Athanasiadis (email: ionathan@iti.gr, alias: ionathan@ieee.org)
118 * @version 5.0
119 * @version $Revision: 5928 $
120 */
121public class FLR
122    extends AbstractClassifier
123    implements Serializable, Summarizable, AdditionalMeasureProducer,
124               TechnicalInformationHandler {
125
126  /** for serialization */
127  static final long serialVersionUID = 3337906540579569626L;
128 
129  public static final float EPSILON = 0.000001f;
130 
131  /** the RuleSet: a vector keeping the learned Fuzzy Lattices */
132  private Vector learnedCode; 
133  /** a double keeping the vignilance parameter rhoa */
134  private double m_Rhoa = 0.5; 
135  /** a Fuzzy Lattice keeping the metric space */
136  private FuzzyLattice bounds; 
137  /** a File pointing to the boundaries file (bounds.txt) */
138  private File m_BoundsFile = new File(""); 
139  /** a flag indicating whether the RuleSet will be displayed */
140  private boolean m_showRules = true; 
141  /** an index of the RuleSet (keeps how many rules are needed for each class) */
142  private int index[]; 
143  /** an array of the names of the classes */
144  private String classNames[]; 
145
146
147  /**
148   * Returns default capabilities of the classifier.
149   *
150   * @return      the capabilities of this classifier
151   */
152  public Capabilities getCapabilities() {
153    Capabilities result = super.getCapabilities();
154    result.disableAll();
155
156    // attributes
157    result.enable(Capability.NUMERIC_ATTRIBUTES);
158    result.enable(Capability.DATE_ATTRIBUTES);
159    result.enable(Capability.MISSING_VALUES);
160
161    // class
162    result.enable(Capability.NOMINAL_CLASS);
163    result.enable(Capability.MISSING_CLASS_VALUES);
164   
165    return result;
166  }
167
168  /**
169   * Builds the FLR Classifier
170   *
171   * @param data the training dataset (Instances)
172       * @throws Exception if the training dataset is not supported or is erroneous
173   */
174  public void buildClassifier(Instances data) throws Exception {
175    // can classifier handle the data?
176    getCapabilities().testWithFail(data);
177
178    // remove instances with missing class
179    data = new Instances(data);
180    data.deleteWithMissingClass();
181
182    // Exceptions statements
183    for (int i = 0; i < data.numAttributes(); i++) {
184      if (i != data.classIndex()) {
185        AttributeStats stats = data.attributeStats(i);
186        if(data.numInstances()==stats.missingCount ||
187           Double.isNaN(stats.numericStats.min) ||
188           Double.isInfinite(stats.numericStats.min))
189          throw new Exception("All values are missing!" +
190              data.attribute(i).toString());
191      } //fi
192    } //for
193
194    if (!m_BoundsFile.canRead()) {
195      setBounds(data);
196    }
197    else
198      try {
199        BufferedReader in = new BufferedReader(new FileReader(m_BoundsFile));
200        String line = in.readLine();
201        bounds = new FuzzyLattice(line);
202      }
203      catch (Exception e) {
204        throw new Exception("Boundaries File structure error");
205      }
206
207    if (bounds.length() != data.numAttributes() - 1) {
208      throw new Exception("Incompatible bounds file!");
209    }
210    checkBounds();
211
212    // Variable Declerations and Initialization
213    index = new int[data.numClasses()];
214    classNames = new String[data.numClasses()];
215    for (int i = 0; i < data.numClasses(); i++) {
216      index[i] = 0;
217      classNames[i] = "missing Class Name";
218    }
219
220    double rhoa = m_Rhoa;
221    learnedCode = new Vector();
222    int searching;
223    FuzzyLattice inputBuffer;
224
225    // Build Classifier (Training phase)
226    if (data.firstInstance().classIsMissing())
227      throw new Exception("In first instance, class is missing!");
228
229    // set the first instance to be the first Rule in the model
230    FuzzyLattice Code = new FuzzyLattice(data.firstInstance(), bounds);
231    learnedCode.addElement(Code);
232    index[Code.getCateg()]++;
233    classNames[Code.getCateg()] = data.firstInstance().stringValue(data.
234        firstInstance().classIndex());
235    // training iteration
236    for (int i = 1; i < data.numInstances(); i++) { //for all instances
237      Instance inst = data.instance(i);
238      int flag =0;
239      for(int w=0;w<inst.numAttributes()-1;w++){
240        if(w!=inst.classIndex() && inst.isMissing(w))
241          flag=flag+1;
242      }
243      if (!inst.classIsMissing()&&flag!=inst.numAttributes()-1) {
244        inputBuffer = new FuzzyLattice( (Instance) data.instance(i), bounds);
245        double[] sigma = new double[ (learnedCode.size())];
246
247        for (int j = 0; j < learnedCode.size(); j++) {
248          FuzzyLattice num = (FuzzyLattice) learnedCode.get(j);
249          FuzzyLattice den = inputBuffer.join(num);
250          double numden = num.valuation(bounds) / den.valuation(bounds);
251          sigma[j] = numden;
252        } //for int j
253
254        do {
255          int winner = 0;
256          double winnerf = sigma[0];
257
258          for (int j = 1; j < learnedCode.size(); j++) {
259            if (winnerf < sigma[j]) {
260              winner = j;
261              winnerf = sigma[j];
262            } //if
263          } //for
264
265          FuzzyLattice num = inputBuffer;
266          FuzzyLattice winnerBox = (FuzzyLattice) learnedCode.get(winner);
267          FuzzyLattice den = winnerBox.join(num);
268          double numden = num.valuation(bounds) / den.valuation(bounds);
269
270          if ( (inputBuffer.getCateg() == winnerBox.getCateg()) &&
271              (rhoa < (numden))) {
272            learnedCode.setElementAt(winnerBox.join(inputBuffer), winner);
273            searching = 0;
274          }
275          else {
276            sigma[winner] = 0;
277            rhoa += EPSILON;
278            searching = 0;
279            for (int j = 0; j < learnedCode.size(); j++) {
280              if (sigma[j] != 0.0) {
281                searching = 1;
282              } //fi
283            } //for
284
285            if (searching == 0) {
286              learnedCode.addElement(inputBuffer);
287              index[inputBuffer.getCateg()]++;
288              classNames[inputBuffer.getCateg()] = data.instance(i).stringValue(
289                  data.instance(i).classIndex());
290            } //fi
291          } //else
292        }
293        while (searching == 1);
294      } //if Class is missing
295
296    } //for all instances
297  } //buildClassifier
298
299  /**
300   * Classifies a given instance using the FLR Classifier model
301   *
302   * @param instance the instance to be classified
303   * @return the class index into which the instance is classfied
304   */
305
306  public double classifyInstance(Instance instance) {
307
308    FuzzyLattice num, den, inputBuffer;
309    inputBuffer = new FuzzyLattice(instance, bounds); // transform instance to fuzzy lattice
310
311    // calculate excitations and winner
312    double[] sigma = new double[ (learnedCode.size())];
313    for (int j = 0; j < learnedCode.size(); j++) {
314      num = (FuzzyLattice) learnedCode.get(j);
315      den = inputBuffer.join(num);
316      sigma[j] = (num.valuation(bounds) / den.valuation(bounds));
317    } //for j
318
319    //find the winner Code (hyperbox)
320    int winner = 0;
321    double winnerf = sigma[0];
322    for (int j = 1; j < learnedCode.size(); j++) {
323      if (winnerf < sigma[j]) {
324        winner = j;
325        winnerf = sigma[j];
326      } //fi
327    } //for j
328
329    FuzzyLattice currentBox = (FuzzyLattice) learnedCode.get(winner);
330    return (double) currentBox.getCateg();
331  } //classifyInstance
332
333  /**
334   * Returns a description of the classifier.
335   *
336   * @return String describing the FLR model
337   */
338  public String toString() {
339    if (learnedCode != null) {
340      String output = "";
341      output = "FLR classifier\n=======================\n Rhoa = " + m_Rhoa;
342      if (m_showRules) {
343        output = output + "\n Extracted Rules (Fuzzy Lattices):\n\n";
344        output = output + showRules();
345        output = output + "\n\n Metric Space:\n" + bounds.toString();
346      }
347      output = output + "\n Total Number of Rules:    " + learnedCode.size() +
348          "\n";
349      for (int i = 0; i < index.length; i++) {
350        output = output + " Rules pointing in Class " + classNames[i] + " :" +
351            index[i] + "\n";
352      }
353      return output;
354    }
355    else {
356      String output = "FLR classifier\n=======================\n Rhoa = " +
357          m_Rhoa;
358      output = output + "No model built";
359      return output;
360    }
361  } //toString
362
363  /**
364   * Returns a superconcise version of the model
365   *
366   * @return String descibing the FLR model very shortly
367   */
368  public String toSummaryString() {
369    String output = "";
370    if (learnedCode == null) {
371      output += "No model built";
372    }
373    else {
374      output = output + "Total Number of Rules: " + learnedCode.size();
375    }
376    return output;
377  } //toSummaryString
378
379  /**
380   * Returns the induced set of Fuzzy Lattice Rules
381   *
382   * @return String containing the ruleset
383   *
384   */
385  public String showRules() {
386    String output = "";
387    for (int i = 0; i < learnedCode.size(); i++) {
388      FuzzyLattice Code = (FuzzyLattice) learnedCode.get(i);
389      output = output + "Rule: " + i + " " + Code.toString();
390    }
391    return output;
392  } //showRules
393
394  /**
395   * Returns an enumeration describing the available options. <p/>
396   *
397   <!-- options-start -->
398   * Valid options are: <p/>
399   *
400   * <pre> -R
401   *  Set vigilance parameter rhoa.
402   *  (a float in range [0,1])</pre>
403   *
404   * <pre> -B
405   *  Set boundaries File
406   *  Note:  The boundaries file is a simple text file containing
407   *  a row with a Fuzzy Lattice defining the metric space.
408   *  For example, the boundaries file could contain the following
409   *  the metric space for the iris dataset:
410   *  [ 4.3  7.9 ]  [ 2.0  4.4 ]  [ 1.0  6.9 ]  [ 0.1  2.5 ]  in Class:  -1
411   *  This lattice just contains the min and max value in each
412   *  dimension.
413   *  In other kind of problems this may not be just a min-max
414   *  operation, but it could contain limits defined by the problem
415   *  itself.
416   *  Thus, this option should be set by the user.
417   *  If ommited, the metric space used contains the mins and maxs
418   *  of the training split.</pre>
419   *
420   * <pre> -Y
421   *  Show Rules</pre>
422   *
423   <!-- options-end -->
424   *
425   * @return enumeration an enumeration of valid options
426   */
427  public Enumeration listOptions() {
428    Vector newVector = new Vector(3);
429
430    newVector.addElement(new Option(
431        "\tSet vigilance parameter rhoa.\n"
432        + "\t(a float in range [0,1])", 
433        "R", 1, "-R"));
434   
435    newVector.addElement(new Option(
436        "\tSet boundaries File\n"
437        + "\tNote:  The boundaries file is a simple text file containing \n"
438        + "\ta row with a Fuzzy Lattice defining the metric space.\n"
439        + "\tFor example, the boundaries file could contain the following \n"
440        + "\tthe metric space for the iris dataset:\n"
441        + "\t[ 4.3  7.9 ]  [ 2.0  4.4 ]  [ 1.0  6.9 ]  [ 0.1  2.5 ]  in Class:  -1\n"
442        + "\tThis lattice just contains the min and max value in each \n"
443        + "\tdimension.\n"
444        + "\tIn other kind of problems this may not be just a min-max \n"
445        + "\toperation, but it could contain limits defined by the problem \n"
446        + "\titself.\n"
447        + "\tThus, this option should be set by the user.\n"
448        + "\tIf ommited, the metric space used contains the mins and maxs \n"
449        + "\tof the training split.", 
450        "B", 1, "-B"));
451
452    newVector.addElement(new Option(
453        "\tShow Rules", 
454        "Y", 0, "-Y"));
455   
456    return newVector.elements();
457  } //listOptions
458
459  /**
460   * Parses a given list of options. <p/>
461   *
462   <!-- options-start -->
463   * Valid options are: <p/>
464   *
465   * <pre> -R
466   *  Set vigilance parameter rhoa.
467   *  (a float in range [0,1])</pre>
468   *
469   * <pre> -B
470   *  Set boundaries File
471   *  Note:  The boundaries file is a simple text file containing
472   *  a row with a Fuzzy Lattice defining the metric space.
473   *  For example, the boundaries file could contain the following
474   *  the metric space for the iris dataset:
475   *  [ 4.3  7.9 ]  [ 2.0  4.4 ]  [ 1.0  6.9 ]  [ 0.1  2.5 ]  in Class:  -1
476   *  This lattice just contains the min and max value in each
477   *  dimension.
478   *  In other kind of problems this may not be just a min-max
479   *  operation, but it could contain limits defined by the problem
480   *  itself.
481   *  Thus, this option should be set by the user.
482   *  If ommited, the metric space used contains the mins and maxs
483   *  of the training split.</pre>
484   *
485   * <pre> -Y
486   *  Show Rules</pre>
487   *
488   <!-- options-end -->
489   *
490   * @param options the list of options as an array of strings
491   * @throws Exception if an option is not supported (
492   */
493  public void setOptions(String[] options) throws Exception {
494    // Option -Y
495    m_showRules = Utils.getFlag('Y', options);
496    // Option -R
497    String rhoaString = Utils.getOption('R', options);
498    if (rhoaString.length() != 0) {
499      m_Rhoa = Double.parseDouble(rhoaString);
500      if (m_Rhoa < 0 || m_Rhoa > 1) {
501        throw new Exception(
502            "Vigilance parameter (rhoa) should be a real number in range [0,1]");
503      }
504    }
505    else
506      m_Rhoa = 0.5;
507
508      // Option -B
509    String boundsString = Utils.getOption('B', options);
510    if (boundsString.length() != 0) {
511      m_BoundsFile = new File(boundsString);
512    } //fi
513    Utils.checkForRemainingOptions(options);
514  } //setOptions
515
516  /**
517   * Gets the current settings of the Classifier.
518   *
519   * @return an array of strings suitable for passing to setOptions
520   */
521  public String[] getOptions() {
522    String[] options = new String[5];
523    int current = 0;
524    options[current++] = "-R";
525    options[current++] = "" + getRhoa();
526    if (m_showRules) {
527      options[current++] = "-Y";
528    }
529    if (m_BoundsFile.toString() != "") {
530      options[current++] = "-B";
531      options[current++] = "" + getBoundsFile();
532    }
533    while (current < options.length) {
534      options[current++] = "";
535    }
536    return options;
537  } // getOptions
538
539  /**
540   * Get rhoa
541   * @return the value of this parameter
542   */
543  public double getRhoa() {
544    return m_Rhoa;
545  }
546
547  /**
548   * Get boundaries File
549   * @return the value of this parameter
550   */
551  public String getBoundsFile() {
552    return m_BoundsFile.toString();
553  }
554
555  /**
556   * Get ShowRules parameter
557   * @return the value of this parameter
558   */
559  public boolean getShowRules() {
560    return m_showRules;
561  }
562
563  /**
564   * Set rhoa
565   * @param newRhoa sets the rhoa value
566   * @throws Exception if rhoa is not in range [0,1]
567   */
568  public void setRhoa(double newRhoa) throws Exception {
569    if (newRhoa < 0 || newRhoa > 1) {
570      throw new Exception(
571          "Vigilance parameter (rhoa) should be a real number in range [0,1]!!!");
572    }
573    m_Rhoa = newRhoa;
574  }
575
576  /**
577   * Set Boundaries File
578   * @param newBoundsFile a new file containing the boundaries
579   */
580  public void setBoundsFile(String newBoundsFile) {
581    m_BoundsFile = new File(newBoundsFile);
582  }
583
584  /**
585   * Set ShowRules flag
586   * @param flag the new value of this parameter
587   */
588  public void setShowRules(boolean flag) {
589    m_showRules = flag;
590  }
591
592  /**
593   * Sets the metric space from the training set using the min-max stats, in case -B option is not used.
594   * @param data is the training set
595   */
596  public void setBounds(Instances data) {
597    // Initialize minmax stats
598    bounds = new FuzzyLattice(data.numAttributes() - 1);
599    int k = 0;
600    for (int i = 0; i < data.numAttributes(); i++) {
601      if (i != data.classIndex()) {
602        AttributeStats stats = data.attributeStats(i);
603        bounds.setMin(k, stats.numericStats.min);
604        bounds.setMax(k, stats.numericStats.max);
605        k = k + 1;
606      } //if
607    } //for
608  } //setBounds
609
610  /**
611   * Checks the metric space
612   */
613  public void checkBounds() {
614    for (int i = 0; i < bounds.length(); i++) {
615      if (bounds.getMin(i) == bounds.getMax(i))
616        bounds.setMax(i, bounds.getMax(i) + EPSILON);
617    }
618  }
619
620  /**
621   * Returns the tip text for this property
622   * @return tip text for this property suitable for
623   * displaying in the explorer/experimenter gui
624   */
625  public String rhoaTipText() {
626    return " The vigilance parameter value" + " (default = 0.75)";
627  }
628
629  /**
630   * Returns the tip text for this property
631   * @return tip text for this property suitable for
632   * displaying in the explorer/experimenter gui
633   */
634  public String boundsFileTipText() {
635    return " Point the filename containing the metric space";
636  }
637
638  /**
639   * Returns the tip text for this property
640   * @return tip text for this property suitable for
641   * displaying in the explorer/experimenter gui
642   */
643  public String showRulesTipText() {
644    return " If true, displays the ruleset.";
645  }
646
647  /**
648   * Returns the value of the named measure
649   * @param additionalMeasureName the name of the measure to query for its value
650   * @return the value of the named measure
651   * @throws IllegalArgumentException if the named measure is not supported
652   */
653  public double getMeasure(String additionalMeasureName) {
654    if (additionalMeasureName.compareToIgnoreCase("measureNumRules") == 0) {
655      return measureNumRules();
656    }
657    else {
658      throw new IllegalArgumentException(additionalMeasureName +
659                                         " not supported (FLR)");
660    }
661  }
662
663  /**
664   * Returns an enumeration of the additional measure names
665   * @return an enumeration of the measure names
666   */
667  public Enumeration enumerateMeasures() {
668    Vector newVector = new Vector(1);
669    newVector.addElement("measureNumRules");
670    return newVector.elements();
671  }
672
673  /**
674   * Additional measure Number of Rules
675   * @return the number of rules induced
676   */
677  public double measureNumRules() {
678    if (learnedCode == null)
679      return 0.0;
680    else
681      return (double) learnedCode.size();
682  }
683
684  /**
685   * Returns a description of the classifier suitable for
686   * displaying in the explorer/experimenter gui
687   * @return the description
688   */
689  public String globalInfo() {
690    return 
691        "Fuzzy Lattice Reasoning Classifier (FLR) v5.0\n\n"
692      + "The Fuzzy Lattice Reasoning Classifier uses the notion of Fuzzy "
693      + "Lattices for creating a Reasoning Environment.\n"
694      + "The current version can be used for classification using numeric predictors.\n\n"
695      + "For more information see:\n\n"
696      + getTechnicalInformation().toString();
697  }
698
699  /**
700   * Returns an instance of a TechnicalInformation object, containing
701   * detailed information about the technical background of this class,
702   * e.g., paper reference or book this class is based on.
703   *
704   * @return the technical information about this class
705   */
706  public TechnicalInformation getTechnicalInformation() {
707    TechnicalInformation        result;
708    TechnicalInformation        additional;
709   
710    result = new TechnicalInformation(Type.INPROCEEDINGS);
711    result.setValue(Field.AUTHOR, "I. N. Athanasiadis and V. G. Kaburlasos and P. A. Mitkas and V. Petridis");
712    result.setValue(Field.TITLE, "Applying Machine Learning Techniques on Air Quality Data for Real-Time Decision Support");
713    result.setValue(Field.BOOKTITLE, "1st Intl. NAISO Symposium on Information Technologies in Environmental Engineering (ITEE-2003)");
714    result.setValue(Field.YEAR, "2003");
715    result.setValue(Field.ADDRESS, "Gdansk, Poland");
716    result.setValue(Field.PUBLISHER, "ICSC-NAISO Academic Press");
717    result.setValue(Field.NOTE, "Abstract in ICSC-NAISO Academic Press, Canada (ISBN:3906454339), pg.51");
718   
719    additional = result.add(Type.UNPUBLISHED);
720    additional.setValue(Field.AUTHOR, "V. G. Kaburlasos and I. N. Athanasiadis and P. A. Mitkas and V. Petridis");
721    additional.setValue(Field.TITLE, "Fuzzy Lattice Reasoning (FLR) Classifier and its Application on Improved Estimation of Ambient Ozone Concentration");
722    additional.setValue(Field.YEAR, "2003");
723   
724    return result;
725  }
726 
727  /**
728   * Returns the revision string.
729   *
730   * @return            the revision
731   */
732  public String getRevision() {
733    return RevisionUtils.extract("$Revision: 5928 $");
734  }
735
736  /**
737   * Main method for testing this class.
738   *
739   * @param args should contain command line arguments for evaluation
740   * (see Evaluation).
741   */
742
743  public static void main(String[] args) {
744    runClassifier(new FLR(), args);
745  }
746
747  /**
748   * <p>Fuzzy Lattice implementation in WEKA </p>
749   *
750   * @author Ioannis N. Athanasiadis
751   * email: ionathan@iti.gr
752   * alias: ionathan@ieee.org
753   * @version 5.0
754   */
755  private class FuzzyLattice
756    implements Serializable, RevisionHandler {
757
758    /** for serialization */
759    static final long serialVersionUID = -3568003680327062404L;
760   
761    private double min[];
762    private double max[];
763    private int categ;
764    private String className;
765
766    //Constructors
767
768    /**
769     * Constructs a Fuzzy Lattice from a instance
770     * @param dR the instance
771     * @param bounds the boundaries file
772     */
773    public FuzzyLattice(Instance dR, FuzzyLattice bounds) {
774      min = new double[dR.numAttributes() - 1];
775      max = new double[dR.numAttributes() - 1];
776      int k = 0;
777      for (int i = 0; i < dR.numAttributes(); i++) {
778        if (i != dR.classIndex()) {
779          if (!dR.isMissing(i)) {
780            min[k] = (dR.value(i) > bounds.getMin(k)) ? dR.value(i) :
781                bounds.getMin(k);
782            max[k] = (dR.value(i) < bounds.getMax(k)) ? dR.value(i) :
783                bounds.getMax(k);
784            k = k + 1;
785          } //if(!dR.isMissing(i))
786          else {
787            min[k] = bounds.getMax(k);
788            max[k] = bounds.getMin(k);
789            k = k + 1;
790          } //else
791        } //if(i!=dR.classIndex())
792      } //for (int i=0; i<dR.numAttributes();i++)
793      categ = (int) dR.value(dR.classIndex());
794      className = dR.stringValue(dR.classIndex());
795    } //FuzzyLattice
796
797    /**
798     * Constructs an empty Fuzzy Lattice of a specific dimension pointing
799     * in Class "Metric Space" (-1)
800     * @param length the dimention of the Lattice
801     */
802    public FuzzyLattice(int length) {
803      min = new double[length];
804      max = new double[length];
805
806      for (int i = 0; i < length; i++) {
807        min[i] = 0;
808        max[i] = 0;
809      }
810      categ = -1;
811      className = "Metric Space";
812    }
813
814    /**
815     * Converts a String to a Fuzzy Lattice pointing in Class "Metric Space" (-1)
816     * Note that the input String should be compatible with the toString() method.
817     * @param rule the input String.
818     */
819    public FuzzyLattice(String rule) {
820      int size = 0;
821      for (int i = 0; i < rule.length(); i++) {
822        String s = rule.substring(i, i + 1);
823        if (s.equalsIgnoreCase("[")) {
824          size++;
825        }
826      }
827      min = new double[size];
828      max = new double[size];
829
830      int i = 0;
831      int k = 0;
832      String temp = "";
833      int s = 0;
834      do {
835        String character = rule.substring(s, s + 1);
836        temp = temp + character;
837        if (character.equalsIgnoreCase(" ")) {
838          if (!temp.equalsIgnoreCase(" ")) {
839            k = k + 1;
840            if (k % 4 == 2) {
841              min[i] = Double.parseDouble(temp);
842            } //if
843            else if (k % 4 == 3) {
844              max[i] = Double.parseDouble(temp);
845              i = i + 1;
846            } //else
847          } // if (!temp.equalsIgnoreCase(" ") ){
848          temp = "";
849        } //if (character.equalsIgnoreCase(seperator)){
850        s = s + 1;
851      }
852      while (i < size);
853      categ = -1;
854      className = "Metric Space";
855    }
856
857    // Functions
858
859    /**
860     * Calculates the valuation function of the FuzzyLattice
861     * @param bounds corresponding boundaries
862     * @return the value of the valuation function
863     */
864    public double valuation(FuzzyLattice bounds) {
865      double resp = 0.0;
866      for (int i = 0; i < min.length; i++) {
867        resp += 1 -
868            (min[i] - bounds.getMin(i)) / (bounds.getMax(i) - bounds.getMin(i));
869        resp += (max[i] - bounds.getMin(i)) /
870            (bounds.getMax(i) - bounds.getMin(i));
871      }
872      return resp;
873    }
874
875    /**
876     * Calcualtes the length of the FuzzyLattice
877     * @return the length
878     */
879    public int length() {
880      return min.length;
881    }
882
883    /**
884     * Implements the Join Function
885     * @param lattice the second fuzzy lattice
886     * @return the joint lattice
887     */
888    public FuzzyLattice join(FuzzyLattice lattice) { // Lattice Join
889      FuzzyLattice b = new FuzzyLattice(lattice.length());
890      int i;
891      for (i = 0; i < lattice.min.length; i++) {
892        b.min[i] = (lattice.min[i] < min[i]) ? lattice.min[i] :
893            min[i];
894        b.max[i] = (lattice.max[i] > max[i]) ? lattice.max[i] :
895            max[i];
896      }
897      b.categ = categ;
898      b.className = className;
899      return b;
900    }
901
902    // Get-Set Functions
903
904    public int getCateg() {
905      return categ;
906    }
907
908    public void setCateg(int i) {
909      categ = i;
910    }
911
912    public String getClassName() {
913      return className;
914    }
915
916    public void setClassName(String s) {
917      className = s;
918    }
919
920    public double getMin(int i) {
921      return min[i];
922    }
923
924    public double getMax(int i) {
925      return max[i];
926    }
927
928    public void setMin(int i, double val) {
929      min[i] = val;
930    }
931
932    public void setMax(int i, double val) {
933      max[i] = val;
934    }
935
936    /**
937     * Returns a description of the Fuzzy Lattice
938     * @return the Fuzzy Lattice and the corresponding Class
939     */
940    public String toString() {
941      String rule = "";
942      for (int i = 0; i < min.length; i++) {
943        rule = rule + "[ " + min[i] + "  " + max[i] + " ]  ";
944      }
945      rule = rule + "in Class:  " + className + " \n";
946      return rule;
947    }
948   
949    /**
950     * Returns the revision string.
951     *
952     * @return          the revision
953     */
954    public String getRevision() {
955      return RevisionUtils.extract("$Revision: 5928 $");
956    }
957  }
958}
959
Note: See TracBrowser for help on using the repository browser.