/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) 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 3 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, see http://www.gnu.org/licenses/ **********************************************************************/ package keel.Algorithms.Fuzzy_Rule_Learning.Genetic.ClassifierFuzzySGERD; import java.util.*; import org.core.*; /** * <p>This class contains the representation of a Rule Set</p> * * @author Written by Alberto Fern�ndez (University of Granada) 29/10/2007 * @author Modifed by Jesus Alcala (University of Granada) 23/05/2009 * @version 1.1 * @since JDK1.5 */ public class RuleBase { ArrayList<Rule> ruleBase; DataBase dataBase; myDataset train; int n_variables, fitness, totalPartitions, totalLabels, typeEvaluation; /** * Maximization * @param a int first number * @param b int second number * @return boolean true if a is better than b */ public boolean BETTER(int a, int b) { if (a > b) { return true; } return false; } /** * Default constructor */ public RuleBase() { } /** * Builds an object for the Rule Base * @param dataBase DataBase Data Base * @param train myDataset Training set * @param typeEvaluation int Code for the evaluation system */ public RuleBase(DataBase dataBase, myDataset train, int typeEvaluation) { this.ruleBase = new ArrayList<Rule> (); this.dataBase = dataBase; this.train = train; this.typeEvaluation = typeEvaluation; this.n_variables = dataBase.numVariables(); this.totalPartitions = dataBase.partitions; this.totalLabels = dataBase.nLabels; } /** * It generates the initial rule set for each partition of the input space (2...L) */ public void initialization() { int i, j, k; int[] rule = new int[n_variables]; for (i = 0; i < this.n_variables; i++) { rule[i] = -1; // don't care } for (i = 0; i < this.n_variables; i++) { for (j = 0; j < this.totalLabels; j++) { rule[i] = j; this.createRule(rule); } rule[i] = -1; // don't care } } /** * It returns the size of the Rule Base * @return int the number of rules */ public int size() { return (this.ruleBase.size()); } /** * It adds a new rule to the rule set * @param rule Rule the new rule */ public void add(Rule rule) { this.ruleBase.add(rule); } /** * It returns a given rule from the RB * @param pos int the rule id * @return Rule a rule of the RB */ public Rule get(int pos) { return (this.ruleBase.get(pos)); } /** * It removes a given rule from the RB * @param pos int the rule id * @return Rule the removed rule */ public Rule remove(int pos) { return (this.ruleBase.remove(pos)); } /** * It sorts the rule base according to the fitness of the rules */ public void sort() { Collections.sort(this.ruleBase); } /** * It creates a new rule and add it to the RB * @param antecedent int[] the antecedent conditions for the rule */ private void createRule(int[] antecedent) { Rule r = new Rule(this.dataBase, this.typeEvaluation); r.asignAntecedent(antecedent); r.setConsequent(this.train); r.evaluation(this.train); r.onNew(); this.ruleBase.add(r); } /** * <p> * Clone Function * </p> * * @return a copy of the RuleBase */ public RuleBase clone() { RuleBase br = new RuleBase(); br.ruleBase = new ArrayList<Rule> (); for (int i = 0; i < this.ruleBase.size(); i++) { br.ruleBase.add(this.ruleBase.get(i).clone()); } br.dataBase = this.dataBase; br.train = this.train; br.typeEvaluation = this.typeEvaluation; br.n_variables = this.n_variables; br.totalPartitions = this.totalPartitions; br.totalLabels = this.totalLabels; br.fitness = this.fitness; return (br); } /** * It performs a copy of the current RB * @return RuleBase a copy of the current RB */ public RuleBase cloneEmpty() { RuleBase br = new RuleBase(); br.ruleBase = new ArrayList<Rule> (); br.dataBase = this.dataBase; br.train = this.train; br.typeEvaluation = this.typeEvaluation; br.n_variables = this.n_variables; br.totalPartitions = this.totalPartitions; br.totalLabels = this.totalLabels; br.fitness = this.fitness; return (br); } /** * It removes a prespecified number of rules from the rule set * @param nRules int the number of rules to remove */ public void removeRules(int nRules) { while (this.ruleBase.size() > nRules) { this.ruleBase.remove(nRules); } } /** * It performs the classification process with the current rule set * @return double the accuracy rate */ public double classify() { evaluate(); return this.getAccuracy(); } /** * It evaluates the rule set */ public void evaluate() { int n_clasificados, Prediction; n_clasificados = 0; for (int j = 0; j < train.size(); j++) { Prediction = this.FRM_WR(train.getExample(j)); if (train.getOutputAsInteger(j) == Prediction) { n_clasificados++; } } this.fitness = n_clasificados; } /** * Fuzzy Reasoning Method * @param example double[] the input example * @return int the predicted class label (id) */ public int FRM(double[] example) { return FRM_WR(example); } /** * Winning Rule FRM * @param example double[] the input example * @return int the class label for the rule with highest membership degree to the example */ private int FRM_WR(double[] example) { int clas = -1; double max = 0.0; for (int i = 0; i < ruleBase.size(); i++) { Rule r = ruleBase.get(i); double produc = r.compatibility(example); if (produc > max) { max = produc; clas = r.clas; } } return clas; } /* private int FRM_WR(double[] example) { boolean twoClasses = false; int clas = -1; double max = 0.0; for (int i = 0; i < ruleBase.size(); i++) { Rule r = ruleBase.get(i); double produc = r.compatibility(example); if (produc > max) { max = produc; clas = r.clas; twoClasses = false; } else if ((produc == max) && (r.clas != clas)) twoClasses = true; } if (twoClasses == true) return (-1); else return clas; } */ /** * It returns the accuracy rate for the rule set * @return double the accuracy rate for the rule set */ public double getAccuracy() { return (double) fitness / train.size(); } /** * It adds the best rules to a new rule base * @param ruleBase RuleBase a given rule base to insert rules * @param nRules int the number of rules to insert */ public void selection(RuleBase ruleBase, int nRules) { while ( (this.ruleBase.size() > nRules) && (ruleBase.size() < nRules)) { ruleBase.add(this.ruleBase.remove(nRules)); } while (this.ruleBase.size() > nRules) { this.ruleBase.remove(nRules); } } /** * It prints the rule base into an string * @return String an string containing the rule set */ public String printString() { int i, j, ant; String[] nombres = train.varNames(); String[] clases = train.classNames(); String cadena = new String(""); ant = 0; for (i = 0; i < ruleBase.size(); i++) { Rule r = ruleBase.get(i); cadena += (i + 1) + ": "; for (j = 0; j < n_variables && r.antecedent[j] < 0; j++) { ; } if (j < n_variables && r.antecedent[j] >= 0) { cadena += nombres[j] + " IS " + r.dataBase.print(j, r.antecedent[j]); ant++; } for (j++; j < n_variables - 1; j++) { if (r.antecedent[j] >= 0) { cadena += " AND " + nombres[j] + " IS " + r.dataBase.print(j, r.antecedent[j]); ant++; } } if (j < n_variables && r.antecedent[j] >= 0) { cadena += " AND " + nombres[j] + " IS " + r.dataBase.print(j, r.antecedent[j]) + ": " + clases[r.clas] + "\n"; ant++; } else { cadena += ": " + clases[r.clas] + "\n"; } } cadena = "@Number of rules: " + ruleBase.size() + " Number of Antecedents by rule: " + ant * 1.0 / ruleBase.size() + "\n\n" + cadena; return (cadena); } /** * It writes the rule set into a file * @param filename String the name of the file */ public void saveFile(String filename) { String stringOut = new String(""); stringOut = printString(); Files.writeFile(filename, stringOut); } }