/*********************************************************************** 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.Associative_Classification.ClassifierFuzzyFARCHD; /** * <p>Title: Rule</p> * <p>Description: This class codes a Fuzzy Rule</p> * <p>Copyright: KEEL Copyright (c) 2008</p> * <p>Company: KEEL </p> * @author Written by Jesus Alcala (University of Granada) 09/02/2011 * @version 1.0 * @since JDK1.6 */ import java.util.*; import org.core.Randomize; public class Rule implements Comparable { int[] antecedent; int clas, nAnts; double conf, supp, wracc; DataBase dataBase; /** * <p> * Create a rule with another one * </p> * @param r This a rule * @return A copy of r */ public Rule(Rule r) { this.antecedent = new int[r.antecedent.length]; for (int k = 0; k < this.antecedent.length; k++) { this.antecedent[k] = r.antecedent[k]; } this.clas = r.clas; this.dataBase = r.dataBase; this.conf = r.conf; this.supp = r.supp; this.nAnts = r.nAnts; this.wracc = r.wracc; } /** * <p> * Create a new rule * </p> * @param dataBase The database * @return A rule */ public Rule(DataBase dataBase) { this.antecedent = new int[dataBase.numVariables()]; for (int i = 0; i < this.antecedent.length; i++) this.antecedent[i] = -1; // Don't care this.clas = -1; this.dataBase = dataBase; this.conf = 0.0; this.supp = 0.0; this.nAnts = 0; this.wracc = 0.0; } /** * <p> * Clone * </p> * @return A copy of the rule */ public Rule clone() { Rule r = new Rule(this.dataBase); r.antecedent = new int[antecedent.length]; for (int i = 0; i < this.antecedent.length; i++) { r.antecedent[i] = this.antecedent[i]; } r.clas = this.clas; r.dataBase = this.dataBase; r.conf = this.conf; r.supp = this.supp; r.nAnts = this.nAnts; r.wracc = this.wracc; return (r); } public void asignaAntecedente(int [] antecedent){ this.nAnts = 0; for (int i = 0; i < antecedent.length; i++) { this.antecedent[i] = antecedent[i]; if (this.antecedent[i] > -1) this.nAnts++; } } public void setConsequent(int clas) { this.clas = clas; } public double matching(double[] example) { return (this.degreeProduct(example)); } private double degreeProduct(double[] example) { double degree; degree = 1.0; for (int i = 0; i < antecedent.length && degree > 0.0; i++) { degree *= dataBase.matching(i, antecedent[i], example[i]); } return (degree * this.conf); } public void setConfidence(double conf) { this.conf = conf; } public void setSupport(double supp) { this.supp = supp; } public void setWracc(double wracc) { this.wracc = wracc; } public double getConfidence() { return (this.conf); } public double getSupport() { return (this.supp); } public double getWracc() { return (this.wracc); } public int getClas() { return (this.clas); } public boolean isSubset(Rule a) { if ((this.clas != a.clas) || (this.nAnts > a.nAnts)) return (false); else { for (int k = 0; k < this.antecedent.length; k++) { if (this.antecedent[k] > -1) { if (this.antecedent[k] != a.antecedent[k]) return (false); } } return (true); } } /** * <p> * Calculate Wracc for this rule * </p> * @param train Training dataset * @param exampleWeight Weights of the patterns * @return the value of the measure Wracc for this rule */ public void calculateWracc (myDataset train, ArrayList<ExampleWeight> exampleWeight) { int i; double n_A, n_AC, n_C, degree; ExampleWeight ex; n_A = n_AC = 0.0; n_C = 0.0; for (i=0; i < train.size(); i++) { ex = exampleWeight.get(i); if (ex.isActive()) { degree = this.matching(train.getExample(i)); if (degree > 0.0) { degree *= ex.getWeight(); n_A += degree; if (train.getOutputAsInteger(i) == this.clas) { n_AC += degree; n_C += ex.getWeight(); } } else if (train.getOutputAsInteger(i) == this.clas) n_C += ex.getWeight(); } } if ((n_A < 0.0000000001) || (n_AC < 0.0000000001) || (n_C < 0.0000000001)) this.wracc = -1.0; else this.wracc = (n_AC / n_C) * ((n_AC / n_A) - train.frecuentClass(this.clas)); } public int reduceWeight (myDataset train, ArrayList<ExampleWeight> exampleWeight) { int i, count; ExampleWeight ex; count = 0; for (i=0; i < train.size(); i++) { ex = exampleWeight.get(i); if (ex.isActive()) { if (this.matching(train.getExample(i)) > 0.0) { ex.incCount(); if ((!ex.isActive()) && (train.getOutputAsInteger(i) == this.clas)) count++; } } } return (count); } public void setLabel(int pos, int label) { if ((antecedent[pos] < 0) && (label > -1)) this.nAnts++; if ((antecedent[pos] > -1) && (label < 0)) this.nAnts--; this.antecedent[pos] = label; } public int compareTo(Object a) { if (((Rule) a).wracc < this.wracc) return -1; if (((Rule) a).wracc > this.wracc) return 1; return 0; } }