/*********************************************************************** 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.Fuzzy_Ish_Selec; /** * <p>Title: </p> * * <p>Description: </p> * * <p>Copyright: Copyright (c) 2007</p> * * <p>Company: </p> * * @author not attributable * @version 1.0 */ import java.util.*; import org.core.Randomize; public class Regla implements Comparable { int[] antecedente; int clase; double peso, p_DC; int tipoCompatibilidad, cubiertos; BaseD baseDatos; boolean n_e; public Regla(Regla r) { this.antecedente = new int[r.antecedente.length]; for (int k = 0; k < this.antecedente.length; k++) { this.antecedente[k] = r.antecedente[k]; } this.baseDatos = r.baseDatos; this.tipoCompatibilidad = r.tipoCompatibilidad; } public Regla(BaseD baseDatos, int tipoCompatibilidad) { this.baseDatos = baseDatos; antecedente = new int[baseDatos.numVariables()]; this.tipoCompatibilidad = tipoCompatibilidad; } public void construyeHeuristica(myDataset train, int ejemplo, double p_DC) { int etiquetas[] = new int[14]; double probabilidades[] = new double[14]; double suma; int n_variables = train.getnInputs(); for (int j = 0; j < n_variables; j++) { //Calculo la probabilidad asociada a cada posible antecedente suma = 0.0; int etiq; for (int k = 0; (k < 4); k++) { //Para cada nivel de granularidad for (int l = 0; l < 2 + k; l++) { etiq = (int) ( (1.5 * k) + (0.5 * k * k) + l); probabilidades[etiq] = baseDatos.pertenencia(k, j, l, train.getExample(ejemplo)[j]); suma += probabilidades[etiq]; } } for (int k = 0; k < 14; k++) { probabilidades[k] /= suma; etiquetas[k] = k; } for (int k = 0; k < 13; k++) { for (int l = k + 1; l < 14; l++) { if (probabilidades[k] > probabilidades[l]) { suma = probabilidades[k]; probabilidades[k] = probabilidades[l]; probabilidades[l] = suma; etiq = etiquetas[k]; etiquetas[k] = etiquetas[l]; etiquetas[l] = etiq; } } } for (int k = 1; k < 14; k++) { probabilidades[k] += probabilidades[k - 1]; } suma = Randomize.Rand(); boolean salir = false; for (int k = 0; (k < 14) && (!salir); k++) { if (probabilidades[k] > suma) { antecedente[j] = etiquetas[k]; salir = true; } } } for (int j = 0; j < n_variables; j++) { //Aplico la probabilidad de D.C. if (p_DC > Randomize.Rand()) { antecedente[j] = 14; //Etiqueta Don't Care } } calcula_consecuente(train); n_e = true; } public void asignaAntecedente(int [] antecedente){ for (int i = 0; i < antecedente.length; i++){ this.antecedente[i] = antecedente[i]; } } public void calcula_consecuente(myDataset train) { int i, mejor_clase; int n_clases = train.getnClasses(); double comp, total, mejor_comp, segun_comp, aux; double[] sumaclases = new double[n_clases]; /* sumaclases acumulara el grado de compatibilidad del antecedente de la regla con los ejemplos de cada clase */ for (i = 0; i < n_clases; i++) { sumaclases[i] = 0.0; } total = 0.0; /* Se calcula la suma por clases */ for (i = 0; i < train.size(); i++) { comp = compatibilidad(train.getExample(i)); if (comp > 0.0) { sumaclases[train.getOutputAsInteger(i)] += comp; total += comp; } } mejor_clase = 0; mejor_comp = sumaclases[0]; segun_comp = sumaclases[1]; if (segun_comp > mejor_comp) { mejor_clase = 1; aux = mejor_comp; mejor_comp = segun_comp; segun_comp = aux; } for (i = 2; i < n_clases; i++) { comp = sumaclases[i]; if (comp >= mejor_comp) { mejor_clase = i; segun_comp = mejor_comp; mejor_comp = comp; } } if (mejor_comp == segun_comp) { this.clase = mejor_clase; peso = -1.0; } clase = mejor_clase; //Asigno la clase consecuente_PCF4(train); //Asigno el peso } public void setClase(int clase) { this.clase = clase; } public void asignaConsecuente(myDataset train, int pesoRegla) { if (pesoRegla == Fuzzy_Ish.CF) { consecuente_CF(train); } else if (pesoRegla == Fuzzy_Ish.PCF_II) { consecuente_PCF2(train); } else if (pesoRegla == Fuzzy_Ish.PCF_IV) { consecuente_PCF4(train); } } public double compatibilidad(double[] ejemplo) { if (tipoCompatibilidad == Fuzzy_Ish.MINIMO) { return compatibilidadMinimo(ejemplo); } else { return compatibilidadProducto(ejemplo); } } private double compatibilidadMinimo(double[] ejemplo) { double minimo, grado_pertenencia; int etiqueta, k, p, et; minimo = 1.0; for (int i = 0; i < antecedente.length; i++) { etiqueta = antecedente[i]; boolean salir = false; for (k = 0, p = 1, et = 0; !salir; i++) { if (etiqueta <= p) { etiqueta -= et; salir = true; } et += 2 + i; p += 3 + i; } grado_pertenencia = baseDatos.pertenencia(k, i, etiqueta, ejemplo[i]); minimo = Math.min(grado_pertenencia, minimo); } return (minimo); } private double compatibilidadProducto(double[] ejemplo) { double producto, grado_pertenencia; int etiqueta, k, p, et; producto = 1.0; for (int i = 0; i < antecedente.length; i++) { etiqueta = antecedente[i]; boolean salir = false; for (k = 0, p = 1, et = 0; !salir; k++) { //System.err.println("k["+k+"], p["+p+"], et["+et+"]"); if (etiqueta <= p) { etiqueta -= et; salir = true; } et += 2 + k; p += 3 + k; } k--; //porque al salir del bucle se incrementa //System.err.println("Obtengo-> [k][i][etiqueta]::["+k+"]["+i+"]["+etiqueta+"]"); grado_pertenencia = baseDatos.pertenencia(k, i, etiqueta, ejemplo[i]); producto = producto * grado_pertenencia; } return (producto); } private void consecuente_CF(myDataset train) { double[] sumaclases = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { sumaclases[i] = 0.0; } double total = 0.0; double comp; /* Se calcula la suma por clases */ for (int i = 0; i < train.size(); i++) { comp = this.compatibilidad(train.getExample(i)); sumaclases[train.getOutputAsInteger(i)] += comp; total += comp; } peso = sumaclases[clase] / total; } private void consecuente_PCF2(myDataset train) { double[] sumaclases = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { sumaclases[i] = 0.0; } double total = 0.0; double comp; /* Se calcula la suma por clases */ for (int i = 0; i < train.size(); i++) { comp = this.compatibilidad(train.getExample(i)); sumaclases[train.getOutputAsInteger(i)] += comp; total += comp; } double suma = (total - sumaclases[clase]) / (train.getnClasses() - 1.0); peso = (sumaclases[clase] - suma) / total; } private void consecuente_PCF4(myDataset train) { double[] sumaclases = new double[train.getnClasses()]; for (int i = 0; i < train.getnClasses(); i++) { sumaclases[i] = 0.0; } double total = 0.0; double comp; /* Se calcula la suma por clases */ for (int i = 0; i < train.size(); i++) { comp = this.compatibilidad(train.getExample(i)); sumaclases[train.getOutputAsInteger(i)] += comp; total += comp; } double suma = total - sumaclases[clase]; if (total == 0) { peso = -1; } else { peso = (sumaclases[clase] - suma) / total; } } public Regla clone() { Regla r = new Regla(baseDatos, tipoCompatibilidad); r.antecedente = new int[antecedente.length]; for (int i = 0; i < this.antecedente.length; i++) { r.antecedente[i] = this.antecedente[i]; } r.clase = clase; r.peso = peso; r.p_DC = p_DC; r.n_e = n_e; return r; } public void mutar(myDataset train, double prob_mut) { for (int k = 0; k < antecedente.length; k++) { if (prob_mut > Randomize.Rand()) { antecedente[k] = Randomize.RandintClosed(0, 15); } } calcula_consecuente(train); } public int compareTo(Object a) { if ( ( (Regla) a).cubiertos < this.cubiertos) { return -1; } if ( ( (Regla) a).cubiertos > this.cubiertos) { return 1; } return 0; } }