/*********************************************************************** 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.AdHoc.Chi_RW; /** * <p>This class contains the structure of a Fuzzy Rule</p> * * @author Written by Alberto Fern�ndez (University of Granada) 29/10/2007 * @version 1.0 * @since JDK1.5 */ public class Rule { Fuzzy[] antecedent; int clas; double weight; int compatibilityType; /** * Default constructor */ public Rule() { } /** * Constructor with parameters * @param n_variables int * @param compatibilityType int */ public Rule(int n_variables, int compatibilityType) { antecedent = new Fuzzy[n_variables]; this.compatibilityType = compatibilityType; } /** * It assigns the class of the rule * @param clas int */ public void setClass(int clas) { this.clas = clas; } /** * It assigns the rule weight to the rule * @param train myDataset the training set * @param ruleWeight int the type of rule weight */ public void assingConsequent(myDataset train, int ruleWeight) { if (ruleWeight == Fuzzy_Chi.CF) { consequent_CF(train); } else if (ruleWeight == Fuzzy_Chi.PCF_II) { consequent_PCF2(train); } else if (ruleWeight == Fuzzy_Chi.PCF_IV) { consequent_PCF4(train); } else if (ruleWeight == Fuzzy_Chi.NO_RW) { weight = 1.0; } } /** * It computes the compatibility of the rule with an input example * @param example double[] The input example * @return double the degree of compatibility */ public double compatibility(double[] example) { if (compatibilityType == Fuzzy_Chi.MINIMUM) { return minimumCompatibility(example); } else { return productCompatibility(example); } } /** * Operator T-min * @param example double[] The input example * @return double the computation the the minimum T-norm */ private double minimumCompatibility(double[] example) { double minimum, membershipDegree; minimum = 1.0; for (int i = 0; i < antecedent.length; i++) { membershipDegree = antecedent[i].Fuzzify(example[i]); minimum = Math.min(membershipDegree, minimum); } return (minimum); } /** * Operator T-product * @param example double[] The input example * @return double the computation the the product T-norm */ private double productCompatibility(double[] example) { double product, membershipDegree; product = 1.0; for (int i = 0; i < antecedent.length; i++) { membershipDegree = antecedent[i].Fuzzify(example[i]); product = product * membershipDegree; } return (product); } /** * Classic Certainty Factor weight * @param train myDataset training dataset */ private void consequent_CF(myDataset train) { double[] classes_sum = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { classes_sum[i] = 0.0; } double total = 0.0; double comp; /* Computation of the sum by classes */ for (int i = 0; i < train.size(); i++) { comp = this.compatibility(train.getExample(i)); classes_sum[train.getOutputAsInteger(i)] += comp; total += comp; } weight = classes_sum[clas] / total; } /** * Penalized Certainty Factor weight II (by Ishibuchi) * @param train myDataset training dataset */ private void consequent_PCF2(myDataset train) { double[] classes_sum = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { classes_sum[i] = 0.0; } double total = 0.0; double comp; /* Computation of the sum by classes */ for (int i = 0; i < train.size(); i++) { comp = this.compatibility(train.getExample(i)); classes_sum[train.getOutputAsInteger(i)] += comp; total += comp; } double sum = (total - classes_sum[clas]) / (train.getnClasses() - 1.0); weight = (classes_sum[clas] - sum) / total; } /** * Penalized Certainty Factor weight IV (by Ishibuchi) * @param train myDataset training dataset */ private void consequent_PCF4(myDataset train) { double[] classes_sum = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { classes_sum[i] = 0.0; } double total = 0.0; double comp; /* Computation of the sum by classes */ for (int i = 0; i < train.size(); i++) { comp = this.compatibility(train.getExample(i)); classes_sum[train.getOutputAsInteger(i)] += comp; total += comp; } double sum = total - classes_sum[clas]; weight = (classes_sum[clas] - sum) / total; } /** * This function detects if one rule is already included in the Rule Set * @param r Rule Rule to compare * @return boolean true if the rule already exists, else false */ public boolean comparison(Rule r) { int contador = 0; for (int j = 0; j < antecedent.length; j++) { if (this.antecedent[j].label == r.antecedent[j].label) { contador++; } } if (contador == antecedent.length) { if (this.clas != r.clas) { //Comparison of the rule weights if (this.weight < r.weight) { //Rule Update this.clas = r.clas; this.weight = r.weight; } } return true; } return false; } }