📄 flr.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FLR.java
* Copyright (C) 2002 Ioannis N. Athanasiadis
*
*/
package weka.classifiers.misc;
import weka.classifiers.*;
import weka.core.*;
import java.io.*;
import java.util.*;
/**
* <p>Fuzzy Lattice Reasoning Classifier</p>
* <p>FLR Classifier implementation in WEKA </p>
* <p>
* <p>The Fuzzy Lattice Reasoning Classifier uses the notion of Fuzzy Lattices
* for creating a Reasoning Environment.
* <p>The current version can be used for classification using numeric predictors.
*
* Valid options are: <p>
*
* -R rhoa<br>
* Set vignilance parameter rhoa (a float in range [0,1])<p>
* -B BoundsPath <br>
* Point the boundaries file (use full path of the file)<p>
* -Y Display the induced ruleset <br>
* (if set true) <p>
* <p> For further information contact I.N.Athanasiadis (ionathan@iti.gr)
*
* @author Ioannis N. Athanasiadis
* @email: ionathan@iti.gr, alias: ionathan@ieee.org
* @version 5.0
*
* <p> This classifier is described in the following papers:
* <p> I. N. Athanasiadis, V. G. Kaburlasos, P. A. Mitkas and V. Petridis
* <i>Applying Machine Learning Techniques on Air Quality Data for Real-Time
* Decision Support</i>, Proceedings 1st Intl. NAISO Symposium on Information
* Technologies in Environmental Engineering (ITEE-2003). Gdansk, Poland:
* ICSC-NAISO Academic Press. Abstract in ICSC-NAISO Academic Press, Canada
* (ISBN:3906454339), pg.51.
*
* <p> V. G. Kaburlasos, I. N. Athanasiadis, P. A. Mitkas and V. Petridis
* <i>Fuzzy Lattice Reasoning (FLR) Classifier and its Application on Improved
* Estimation of Ambient Ozone Concentration</i>, unpublished working paper (2003)
*/
public class FLR
extends Classifier
implements Serializable, Summarizable, AdditionalMeasureProducer {
public static final float EPSILON = 0.000001f;
private Vector learnedCode; // the RuleSet: a vector keeping the learned Fuzzy Lattices
private double m_Rhoa = 0.5; // a double keeping the vignilance parameter rhoa
private FuzzyLattice bounds; // a Fuzzy Lattice keeping the metric space
private File m_BoundsFile = new File(""); // a File pointing to the boundaries file (bounds.txt)
private boolean m_showRules = true; // a flag indicating whether the RuleSet will be displayed
private int index[]; // an index of the RuleSet (keeps how many rules are needed for each class)
private String classNames[]; // an array of the names of the classes
/**
* Builds the FLR Classifier
*
* @param data the training dataset (Instances)
* @exception Exception if the training dataset is not supported or is erroneous
*/
public void buildClassifier(Instances data) throws Exception {
// Exceptions statements
if (data.checkForStringAttributes())
throw new Exception("Can't handle string attributes!");
if (data.classAttribute().isNumeric())
throw new Exception("Class is numeric!");
if (data.numInstances() == 0 || data.numAttributes() == 0 || data.numAttributes()==1)
throw new Exception("Training dataset is empty!");
for (int i = 0; i < data.numAttributes(); i++) {
if (i != data.classIndex()) {
if (data.attribute(i).isNominal())
throw new Exception("Can't handle nominal Attributes");
AttributeStats stats = data.attributeStats(i);
if(data.numInstances()==stats.missingCount ||
Double.isNaN(stats.numericStats.min) ||
Double.isInfinite(stats.numericStats.min))
throw new Exception("All values are missing!" +
data.attribute(i).toString());
} //fi
} //for
if (data.numClasses() < 0) {
throw new Exception("Dataset has no class attribute!");
}
if (!m_BoundsFile.canRead()) {
setBounds(data);
}
else
try {
BufferedReader in = new BufferedReader(new FileReader(m_BoundsFile));
String line = in.readLine();
bounds = new FuzzyLattice(line);
}
catch (Exception e) {
throw new Exception("Boundaries File structure error");
}
if (bounds.length() != data.numAttributes() - 1) {
throw new Exception("Incompatible bounds file!");
}
checkBounds();
// Variable Declerations and Initialization
index = new int[data.numClasses()];
classNames = new String[data.numClasses()];
for (int i = 0; i < data.numClasses(); i++) {
index[i] = 0;
classNames[i] = "missing Class Name";
}
double rhoa = m_Rhoa;
learnedCode = new Vector();
int searching;
FuzzyLattice inputBuffer;
// Build Classifier (Training phase)
if (data.firstInstance().classIsMissing())
throw new Exception("In first instance, class is missing!");
// set the first instance to be the first Rule in the model
FuzzyLattice Code = new FuzzyLattice(data.firstInstance(), bounds);
learnedCode.addElement(Code);
index[Code.getCateg()]++;
classNames[Code.getCateg()] = data.firstInstance().stringValue(data.
firstInstance().classIndex());
// training iteration
for (int i = 1; i < data.numInstances(); i++) { //for all instances
Instance inst = data.instance(i);
int flag =0;
for(int w=0;w<inst.numAttributes()-1;w++){
if(w!=inst.classIndex() && inst.isMissing(w))
flag=flag+1;
}
if (!inst.classIsMissing()&&flag!=inst.numAttributes()-1) {
inputBuffer = new FuzzyLattice( (Instance) data.instance(i), bounds);
double[] sigma = new double[ (learnedCode.size())];
for (int j = 0; j < learnedCode.size(); j++) {
FuzzyLattice num = (FuzzyLattice) learnedCode.get(j);
FuzzyLattice den = inputBuffer.join(num);
double numden = num.valuation(bounds) / den.valuation(bounds);
sigma[j] = numden;
} //for int j
do {
int winner = 0;
double winnerf = sigma[0];
for (int j = 1; j < learnedCode.size(); j++) {
if (winnerf < sigma[j]) {
winner = j;
winnerf = sigma[j];
} //if
} //for
FuzzyLattice num = inputBuffer;
FuzzyLattice winnerBox = (FuzzyLattice) learnedCode.get(winner);
FuzzyLattice den = winnerBox.join(num);
double numden = num.valuation(bounds) / den.valuation(bounds);
if ( (inputBuffer.getCateg() == winnerBox.getCateg()) &&
(rhoa < (numden))) {
learnedCode.setElementAt(winnerBox.join(inputBuffer), winner);
searching = 0;
}
else {
sigma[winner] = 0;
rhoa += EPSILON;
searching = 0;
for (int j = 0; j < learnedCode.size(); j++) {
if (sigma[j] != 0.0) {
searching = 1;
} //fi
} //for
if (searching == 0) {
learnedCode.addElement(inputBuffer);
index[inputBuffer.getCateg()]++;
classNames[inputBuffer.getCateg()] = data.instance(i).stringValue(
data.instance(i).classIndex());
} //fi
} //else
}
while (searching == 1);
} //if Class is missing
} //for all instances
} //buildClassifier
/**
* Classifies a given instance using the FLR Classifier model
*
* @param instance the instance to be classified
* @return the class index into which the instance is classfied
*/
public double classifyInstance(Instance instance) {
FuzzyLattice num, den, inputBuffer;
inputBuffer = new FuzzyLattice(instance, bounds); // transform instance to fuzzy lattice
// calculate excitations and winner
double[] sigma = new double[ (learnedCode.size())];
for (int j = 0; j < learnedCode.size(); j++) {
num = (FuzzyLattice) learnedCode.get(j);
den = inputBuffer.join(num);
sigma[j] = (num.valuation(bounds) / den.valuation(bounds));
} //for j
//find the winner Code (hyperbox)
int winner = 0;
double winnerf = sigma[0];
for (int j = 1; j < learnedCode.size(); j++) {
if (winnerf < sigma[j]) {
winner = j;
winnerf = sigma[j];
} //fi
} //for j
FuzzyLattice currentBox = (FuzzyLattice) learnedCode.get(winner);
return (double) currentBox.getCateg();
} //classifyInstance
/**
* Returns a description of the classifier.
*
* @return String describing the FLR model
*/
public String toString() {
if (learnedCode != null) {
String output = "";
output = "FLR classifier\n=======================\n Rhoa = " + m_Rhoa;
if (m_showRules) {
output = output + "\n Extracted Rules (Fuzzy Lattices):\n\n";
output = output + showRules();
output = output + "\n\n Metric Space:\n" + bounds.toString();
}
output = output + "\n Total Number of Rules: " + learnedCode.size() +
"\n";
for (int i = 0; i < index.length; i++) {
output = output + " Rules pointing in Class " + classNames[i] + " :" +
index[i] + "\n";
}
return output;
}
else {
String output = "FLR classifier\n=======================\n Rhoa = " +
m_Rhoa;
output = output + "No model built";
return output;
}
} //toString
/**
* Returns a superconcise version of the model
*
* @return String descibing the FLR model very shortly
*/
public String toSummaryString() {
String output = "";
if (learnedCode == null) {
output += "No model built";
}
else {
output = output + "Total Number of Rules: " + learnedCode.size();
}
return output;
} //toSummaryString
/**
* Returns the induced set of Fuzzy Lattice Rules
*
* @return String containing the ruleset
*
*/
public String showRules() {
String output = "";
for (int i = 0; i < learnedCode.size(); i++) {
FuzzyLattice Code = (FuzzyLattice) learnedCode.get(i);
output = output + "Rule: " + i + " " + Code.toString();
}
return output;
} //showRules
/**
* Returns an enumeration describing the available options.
*
* Valid options are: <p>
*
* -R rhoa<br>
* Set vignilance parameter rhoa (a float in range [0,1])<p>
* -B BoundsPath <br>
* Set the path pointing to the boundaries file (a full path of the file)<p>
* -Y Display the induced ruleset <br>
* (if set true) <p>
*
* Note: The boundaries file is a simple text file containing a row with a
* Fuzzy Lattice defining the metric space .
* For example, the boundaries file could contain the following the metric
* space for the iris dataset:
* <br> [ 4.3 7.9 ] [ 2.0 4.4 ] [ 1.0 6.9 ] [ 0.1 2.5 ] in Class: -1
* <br> This lattice just contains the min and max value in each dimention.
* In other kind of problems this may not be just a min-max operation, but it
* could contain limits defined by the problem itself.
* Thus, this option should be set by the user.
* If ommited, the metric space used contains the mins and maxs of the training split.
*
* @return enumeration an enumeration of valid options
*/
public Enumeration listOptions() {
Vector newVector = new Vector(3);
newVector.addElement(new Option("\tSet vigilance parameter rhoa.", "R", 1,
"-R"));
newVector.addElement(new Option("\tSet boundaries File", "B", 1, "-B"));
newVector.addElement(new Option("\tShow Rules", "Y", 0, "-Y"));
return newVector.elements();
} //listOptions
/**
* Parses a given list of options.
*
* @param options the list of options as an array of strings
* @exception Exception if an option is not supported (
*/
public void setOptions(String[] options) throws Exception {
// Option -Y
m_showRules = Utils.getFlag('Y', options);
// Option -R
String rhoaString = Utils.getOption('R', options);
if (rhoaString.length() != 0) {
m_Rhoa = Double.parseDouble(rhoaString);
if (m_Rhoa < 0 || m_Rhoa > 1) {
throw new Exception(
"Vigilance parameter (rhoa) should be a real number in range [0,1]");
}
}
else
m_Rhoa = 0.5;
// Option -B
String boundsString = Utils.getOption('B', options);
if (boundsString.length() != 0) {
m_BoundsFile = new File(boundsString);
} //fi
Utils.checkForRemainingOptions(options);
} //setOptions
/**
* Gets the current settings of the Classifier.
*
* @return an array of strings suitable for passing to setOptions
*/
public String[] getOptions() {
String[] options = new String[5];
int current = 0;
options[current++] = "-R";
options[current++] = "" + getRhoa();
if (m_showRules) {
options[current++] = "-Y";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -