/*********************************************************************** 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.ClassifierMOGUL; /** * <p> * @author Written by Jesus Alcala Fernandez (University of Granada) 01/01/2004 * @author Modified by Francisco Jos� Berlanga (University of Ja�n) 09/12/2008 * @version 1.0 * @since JDK 1.6 * </p> */ import java.util.ArrayList; class Adap { /** * <p> * Contains the functions for calculate the matching degree, ... between the rules and the examples * </p> */ public static double omega, K; public double[] grado_pertenencia; public double[] puntos; public double F, G, g, PC; public int EmparejaAnt; public double ClaTra, ClaTst; public int tipo_fitness, tipo_reglas, compa; public MyDataset tabla; public RuleBase base_reglas; public T_FRM frm; /** * <p> * Constructor * </p> * @param training MyDataset The set of examples * @param base RuleBase The Rule Base * @param FRM T_FRM The FRM used * @param tipo int The type of fuzzy rule * @param compatibilidad The association degree function */ public Adap(MyDataset training, RuleBase base, T_FRM FRM, int tipo, int compatibilidad) { tabla = training; base_reglas = base; tipo_reglas = tipo; frm = FRM; compa = compatibilidad; puntos = new double[tabla.n_variables]; grado_pertenencia = new double[tabla.n_variables]; } /** * <p> * Returns the minimum of two values * </p> * @param x double The first value * @param y double The second value * @return The winner value */ public static double Minimum(double x, double y) { if (x < y) { return (x); } else { return (y); } } /** * <p> * Returns the maximum of two values * </p> * @param x double The first value * @param y double The second value * @return The winner value */ public static double Maximum(double x, double y) { if (x > y) { return (x); } else { return (y); } } /* ------------------------------------------------------------------ ----------- Obtaining the greatest value of an vector ------------ If all the vector values are zere, it returns -1. Repetido is equal 0 if the greatest value is not repeated and it is equal 1 in the other case. ------------------------------------------------------------------ */ private int MayorD(double[] s, int n, ArrayList < int[] > milista) { int[] aux1 = new int[1]; aux1 = milista.get(0); int repetido = aux1[0]; int i, mayor; double m; repetido = 0; mayor = -1; m = 0.0; for (i = 0; i < n; i++) { if (s[i] > m) { m = s[i]; mayor = i; repetido = 0; } else if (s[i] == m) { repetido = 1; } } aux1[0] = repetido; milista.add(0, aux1); return (mayor); } /* --------------------------------------------------------------------- Obtaining the position of the smallest value of a vector of double numbers. If all the element of the vector are equal to zero, it returns -1 --------------------------------------------------------------------- */ private int MenorD(double[] s, int n, ArrayList < int[] > milista) { int[] aux1 = new int[1]; aux1 = milista.get(0); int repetido = aux1[0]; int i, menor; double m; repetido = 0; menor = -1; m = 10000.0; for (i = 0; i < n; i++) { if (s[i] < m) { m = s[i]; menor = i; repetido = 0; } else if (s[i] == m) { repetido = 1; } } aux1[0] = repetido; milista.add(0, aux1); return (menor); } /* ------------------------------------------------------------------------ C.A.R. Hoare sorting algorithm. ------------------------------------------------------------------------ */ private void Or(double[] v, int izq, int der) { int i, j; double x, y; i = izq; j = der; x = v[(izq + der) / 2]; do { while (v[i] > x && i < der) { i++; } while (x > v[j] && j > izq) { j--; } if (i <= j) { y = v[i]; v[i] = v[j]; v[j] = y; i++; j--; } } while (i <= j); if (izq < j) { Or(v, izq, j); } if (i < der) { Or(v, i, der); } } private double SumaPonderada(double[] a, double[] w, int n) { int i; double suma; suma = 0.0; for (i = 0; i < n; i++) { suma = suma + a[i] * w[i]; } return (suma); } /* ------------------------------------------------------------------------- FITNESS FUNCTION ------------------------------------------------------------------------- */ /* ------------------------- Criteria of rules -------------------------- */ /** * <p> * Returns the matching degree of the rule "Ri(ek)" with the instance "ejem" * </p> * @param indiv Structure The individual enconding the rule * @param ejem double[] The given example * @return double The matching degree */ public double RuleCoversExample(Structure indiv, double[] ejem) { int i, pos_individuo; double minimo_ant, minimo_con; FuzzySet D = new FuzzySet(); EmparejaAnt = 0; for (i = 0; i < tabla.n_inputs; i++) { pos_individuo = tabla.n_inputs + 3 * i; D.x0 = indiv.Gene[pos_individuo]; D.x1 = indiv.Gene[pos_individuo + 1]; D.x2 = indiv.Gene[pos_individuo + 1]; D.x3 = indiv.Gene[pos_individuo + 2]; D.y = 1; grado_pertenencia[i] = base_reglas.Fuzzification(ejem[i], D); } minimo_ant = 1; minimo_con = 1; for (i = 0; i < tabla.n_inputs; i++) { if (grado_pertenencia[i] < minimo_ant) { minimo_ant = grado_pertenencia[i]; } } if (minimo_ant > 0) { EmparejaAnt = 1; } switch (tipo_reglas) { case 1: case 2: if (indiv.Consecuente[0].clase == ejem[tabla.n_inputs]) { minimo_con = indiv.Consecuente[0].gcerteza; } else { minimo_con = 0.0; } break; case 3: minimo_con = indiv.Consecuente[(int) ejem[tabla.n_inputs]].gcerteza; break; } return (minimo_ant * minimo_con); } /** * <p> * Calcules the rule's criteria by the rule "cromosoma": * - High frequency values [Her95] * - High average covering degree over positive examples [Her95] * - Small negative example set [Gon95] * </p> * @param indiv Structure The invididual encoding the rule */ public void RulesCriteria(Structure indiv) { int i, n_ejem_pos, n_ejem_neg, n_ejem_ya_cub; double RCE, frec_acumulada, SumaRCEpositivos, umbral; n_ejem_pos = n_ejem_neg = 0; frec_acumulada = SumaRCEpositivos = 0.0; /* we count the number of negative and positive examples */ for (i = 0; i < tabla.long_tabla; i++) { RCE = RuleCoversExample(indiv, tabla.datos[i].ejemplo); if (tabla.datos[i].cubierto == 0) { frec_acumulada += RCE; if (RCE >= omega) { /* If the example has a cover higher than omega*/ /* then it's considered a positive example */ n_ejem_pos++; SumaRCEpositivos += RCE; } } /* If the inputs is covered and the outputs isn't then the example is negative */ if (RCE == 0.0 && EmparejaAnt > 0) { n_ejem_neg++; } } /* Rule's frecuency [Her95] */ F = frec_acumulada / tabla.no_cubiertos; /* Average covering degree over positive examples [Her95] */ if (n_ejem_pos > 0) { G = SumaRCEpositivos / (double) n_ejem_pos; } else { G = 0.0; } /* Penalty on the set of negative examples [Gon95] */ umbral = K * n_ejem_pos; /* we don't penalize if the number of negative examples is less or equal than "umbral" */ if (n_ejem_neg <= umbral) { g = 1.0; } else { g = 1.0 / (n_ejem_neg - umbral + Math.exp(1.0)); } /* If we use the fitness function with penalty by overfitting, we'll calculate this penalty */ if (tipo_fitness == 2) { n_ejem_ya_cub = 0; for (i = 0; i < tabla.long_tabla; i++) { RCE = RuleCoversExample(indiv, tabla.datos[i].ejemplo); /* If the example was covered by another rule it's counted for calculating the penalty */ if (tabla.datos[i].cubierto > 0 && RCE != 0) { n_ejem_ya_cub++; } if (n_ejem_ya_cub <= umbral) { PC = 1.0; } else { PC = 1.0 / (n_ejem_ya_cub - umbral + Math.exp(1.0)); } } } } /** * <p> * Calculates the clasification accuracy in training and test data * </p> * @param training boolean TRUE for training data. FALSE for test data * @param tabla MyDataset The set of examples */ public void Clasification_accuracy(boolean training, MyDataset tabla) { double clasi = 100.0 * Clasification(tabla); if (training == true) { ClaTra = clasi; } else { ClaTst = clasi; } } /** * <p> * Obtains the correct percentaje for the examples in the set "t" * </p> * @param t MyDataset The set of examples * @return double The correct percentage on the data in "t" dataset */ public double Clasification(MyDataset t) { int i, mc, mejor_clase, contador, mejor_regla, num_ejemplos; double porcentaje, produc; ArrayList<int[]> lista1 = new ArrayList<int[]>(1); ArrayList<double[]> lista2 = new ArrayList<double[]>(1); int[] aux1 = new int[2]; double[] aux2 = new double[1]; mc = 0; contador = 0; mejor_clase = 0; mejor_regla = 0; produc = 0.0; for (i = 0; i < t.long_tabla; i++) { aux1[0] = mejor_clase; aux1[1] = mejor_regla; lista1.add(0, aux1); aux2[0] = produc; lista2.add(0, aux2); switch (frm.fagre) { case 0: BuscarMejorClase1(lista1, lista2, t.datos[i].ejemplo); break; case 1: MejorSumaClases(lista1, lista2, t.datos[i].ejemplo); break; case 2: MejorMedia(lista1, lista2, t.datos[i].ejemplo); break; case 3: BuscarMejorClaseASOWA(lista1, lista2, t.datos[i].ejemplo); break; case 4: BuscarMejorClaseOSOWA(lista1, lista2, t.datos[i].ejemplo); break; case 5: BuscarMejorClaseQUASIARIT(lista1, lista2, t.datos[i].ejemplo); break; case 6: BuscarMejorClaseBADD(lista1, lista2, t.datos[i].ejemplo); break; case 7: BuscarMejorClaseOWA(lista1, lista2, t.datos[i].ejemplo); break; case 8: BuscarMejorClaseQUASIOWA(lista1, lista2, t.datos[i].ejemplo); } aux1 = lista1.get(0); mejor_clase = aux1[0]; mejor_regla = aux1[1]; aux2 = lista2.get(0); produc = aux2[0]; /* If the maximum compatibility is greatest that zero, the example is classified. Otherwise, the example is considered as not classified */ if ((produc > 0.0) && (mejor_clase == (int) t.datos[i].ejemplo[t.n_inputs])) { contador++; } } porcentaje = ((double) contador) / t.long_tabla; return (porcentaje); } /** * <p> * Obtains the best class for the given example according to the FRM used * </p> * @param t MyDataset The set of examples * @param n_ejemplo int The position of the example in the set of examples * @return int The obtained class */ public int Clasification(MyDataset t, int n_ejemplo) { int mejor_clase, mejor_regla; double produc; ArrayList<int[]> lista1 = new ArrayList<int[]>(1); ArrayList<double[]> lista2 = new ArrayList<double[]>(1); int[] aux1 = new int[2]; double[] aux2 = new double[1]; mejor_clase = 0; mejor_regla = 0; produc = 0.0; aux1[0] = mejor_clase; aux1[1] = mejor_regla; lista1.add(0, aux1); aux2[0] = produc; lista2.add(0, aux2); switch (frm.fagre) { case 0: BuscarMejorClase1(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 1: MejorSumaClases(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 2: MejorMedia(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 3: BuscarMejorClaseASOWA(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 4: BuscarMejorClaseOSOWA(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 5: BuscarMejorClaseQUASIARIT(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 6: BuscarMejorClaseBADD(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 7: BuscarMejorClaseOWA(lista1, lista2, t.datos[n_ejemplo].ejemplo); break; case 8: BuscarMejorClaseQUASIOWA(lista1, lista2, t.datos[n_ejemplo].ejemplo); } aux1 = lista1.get(0); mejor_clase = aux1[0]; mejor_regla = aux1[1]; aux2 = lista2.get(0); produc = aux2[0]; /* If the maximum compatibility is greatest that zero, the example is classified. Otherwise, the example is considered as not classified */ if (produc <= 0.0) { mejor_clase = -1; } return (mejor_clase); } /* ----------------------------------------------------------------------- ------------------ FRM 1 (Classic) ------------------- ----------------------------------------------------------------------- */ private void BuscarMejorClase1(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; FuzzySet[] D = new FuzzySet[tabla.n_inputs]; for (int i = 0; i < tabla.n_inputs; i++) { D[i] = new FuzzySet(); } int r; double max, produc, resu, aux2; int l, c; r = 0; max = 0.0; c = -1; while (r < base_reglas.n_reglas) { for (int i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } produc = MatchingDegree(ejemplo, D); switch (tipo_reglas) { case 2: produc = produc * base_reglas.Consecuentes[r][0].gcerteza; break; case 3: c = -1; /* Look for the best class for this rule */ aux2 = 0.0; for (l = 0; l < tabla.nClasses; l++) { resu = produc * base_reglas.Consecuentes[r][l].gcerteza; if (resu > aux2) { aux2 = resu; c = l; } } produc = aux2; } if (produc > max) { max = produc; mejor_regla = r; switch (tipo_reglas) { case 1: case 2: mejor_clase = base_reglas.Consecuentes[r][0].clase; break; case 3: mejor_clase = c; } } r++; } compatib = max; auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ---------------------------------------------------------------------- ---------------------- FRM 2 (Normalized Sum) ------------------------ ----------------------------------------------------------------------- */ private void MejorSumaClases(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } int r; double produc, resu; int l, c, i, aux; double[] suma = new double[tabla.nClasses]; for (i = 0; i < tabla.nClasses; i++) { suma[i] = 0.0; } /* Calculation of the compatibility degree among the example and the rules of each one of the classes */ r = 0; while (r < base_reglas.n_reglas) { for (i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } produc = MatchingDegree(ejemplo, D); switch (tipo_reglas) { case 1: if (produc > 0.0) { suma[base_reglas.Consecuentes[r][0].clase] += produc; } break; case 2: produc = produc * base_reglas.Consecuentes[r][0].gcerteza; if (produc > 0.0) { suma[base_reglas.Consecuentes[r][0].clase] += produc; } break; case 3: for (l = 0; l < tabla.nClasses; l++) { resu = produc * base_reglas.Consecuentes[r][l].gcerteza; if (resu > 0.0) { suma[l] += resu; } } } r++; } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; aux = 0; auxiliar[0] = aux; lista1.add(0, auxiliar); c = MayorD(suma, tabla.nClasses, lista1); auxiliar = lista1.get(0); aux = auxiliar[0]; if (c != -1) { mejor_clase = c; compatib = suma[c]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* --------------------------------------------------------------------------- ----------------------------- FRM 3 (Arithmetic Mean) ---------------------- --------------------------------------------------------------------------- */ private void MejorMedia(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } int r; double produc, resu; double[] suma = new double[tabla.nClasses]; double[] cociente = new double[tabla.nClasses]; int l, c, i, pos, aux; int[] n = new int[tabla.nClasses]; for (i = 0; i < tabla.nClasses; i++) { suma[i] = 0.0; n[i] = 0; } /* Calculation of the compatibility degree among the example and the rules of each one of the classes */ r = 0; while (r < base_reglas.n_reglas) { for (i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } produc = MatchingDegree(ejemplo, D); switch (tipo_reglas) { case 1: if (produc > 0.0) { pos = base_reglas.Consecuentes[r][0].clase; suma[pos] += produc; n[pos]++; } break; case 2: produc = produc * base_reglas.Consecuentes[r][0].gcerteza; if (produc > 0.0) { pos = base_reglas.Consecuentes[r][0].clase; suma[pos] += produc; n[pos]++; } break; case 3: for (l = 0; l < tabla.nClasses; l++) { resu = produc * base_reglas.Consecuentes[r][l].gcerteza; if (resu > 0.0) { suma[l] += resu; n[l]++; } } } r++; } /* Calculation of the mean by classes */ for (i = 0; i < tabla.nClasses; i++) { if (n[i] > 0) { cociente[i] = suma[i] / n[i]; } else { cociente[i] = 0.0; } } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; aux = 0; auxiliar[0] = aux; lista1.add(0, auxiliar); c = MayorD(cociente, tabla.nClasses, lista1); auxiliar = lista1.get(0); aux = auxiliar[0]; if (c != -1) { mejor_clase = c; compatib = cociente[c]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------ --------------------- FRM 4 (OWA) --------------------------- ------------------------------------------------------------------------ */ private double Q(double i, double a, double b) { if (i < a) { return (0); } else if (i <= b) { return ((i - a) / (b - a)); } else { return (1); } } /* ------------------------------------------------------------------------ */ private double Peso(int i, double a, double b, int n) { double resu; if (i == 0) { resu = Q((i + 1) / ((double) n), a, b); } else { resu = Q((i + 1) / ((double) n), a, b) - Q(i / ((double) n), a, b); } return (resu); } /* ------------------------------------------------------------------------ */ private void ObtenerPesos(ArrayList < double[] > lista, int contador, double a, double b) { double[] w = new double[contador]; w = lista.get(0); int i; for (i = 0; i < contador; i++) { w[i] = Peso(i, a, b, contador); } lista.add(0, w); } /* ------------------------------------------------------------------------ */ private double CalcularOWA(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu; int r, contador, j; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; /* Look for the "A" vector for the class "clase" */ while (r < base_reglas.n_reglas) { for (int i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; } } } r++; } if (contador != 0) { /* Sort "A" vector */ Or(A, 0, contador - 1); ArrayList<double[]> lista1 = new ArrayList<double[]>(1); double[] w = new double[contador]; lista1.add(0, w); /* Obtaining the weights */ ObtenerPesos(lista1, contador, frm.a, frm.b); w = lista1.get(0); /* Calculating the final value for owa */ resu = SumaPonderada(A, w, contador); return (resu); } else { return (0); } } /* ------------------------------------------------------------------------ */ private void BuscarMejorClaseOWA(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] owa = new double[tabla.nClasses]; int i, repetido, pos; for (i = 0; i < tabla.nClasses; i++) { owa[i] = CalcularOWA(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(owa, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = owa[pos]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------- ----------------------- FRM 5 (OR-LIKE SOWA) -------------------------- ------------------------------------------------------------------------- */ private double CalcularOSOWA(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu, amax, suma; int r, contador, j, posicion, repetido; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; suma = 0.0; /* Look for the set of value to be added for the class "clase" */ while (r < base_reglas.n_reglas) { for (int i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } } r++; } if (contador == 0) { return (0); } else { ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); posicion = MayorD(A, contador, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; amax = A[posicion]; resu = (1 - frm.a) * (1 / (double) contador) * suma + frm.a * amax; return (resu); } } /* ------------------------------------------------------------------------- */ private void BuscarMejorClaseOSOWA(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] osowa = new double[tabla.nClasses]; int i, pos, repetido; for (i = 0; i < tabla.nClasses; i++) { osowa[i] = CalcularOSOWA(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(osowa, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = osowa[pos]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------- ----------------------- FRM 6 (AND-LIKE SOWA) -------------------------- ------------------------------------------------------------------------- */ private double CalcularASOWA(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu, amax, suma; int r, contador, j, posicion, repetido; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; suma = 0.0; /* Look for the set of value to be added for the class "clase" */ while (r < base_reglas.n_reglas) { for (int i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } } r++; } if (contador == 0) { return (0); } else { ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); posicion = MenorD(A, contador, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; amax = A[posicion]; resu = (1 - frm.a) * (1 / (double) contador) * suma + frm.a * amax; return (resu); } } /* ------------------------------------------------------------------------ */ private void BuscarMejorClaseASOWA(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] asowa = new double[tabla.nClasses]; int i, pos, repetido; for (i = 0; i < tabla.nClasses; i++) { asowa[i] = CalcularASOWA(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(asowa, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = asowa[pos]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------- ----------------------- FRM 7 (QUASI-OWA) -------------------------- ------------------------------------------------------------------------- */ private double CalcularQUASIOWA(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu, amax, suma; int r, contador, j, posicion, repetido, i; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; suma = 0.0; /* Look for the set of value to be added for the class "clase" */ while (r < base_reglas.n_reglas) { for (i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma += comp; } } } r++; } if (contador != 0) { /* Sort "A" vector */ Or(A, 0, contador - 1); /* Obtaning the weights */ ArrayList<double[]> lista1 = new ArrayList<double[]>(1); double[] w = new double[contador]; lista1.add(0, w); ObtenerPesos(lista1, contador, frm.a, frm.b); w = lista1.get(0); /* Calculation of the final value for quasiowa */ for (i = 0; i < contador; i++) { A[i] = Math.pow(A[i], frm.p); } resu = SumaPonderada(A, w, contador); resu = Math.pow(resu, 1 / frm.p); return (resu); } else { return (0); } } /* --------------------------------------------------------------------------- */ private void BuscarMejorClaseQUASIOWA(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] quasiowa = new double[tabla.nClasses]; int i, pos, repetido; for (i = 0; i < tabla.nClasses; i++) { quasiowa[i] = CalcularQUASIOWA(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(quasiowa, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = quasiowa[pos]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------- ----------------------- FRM 8 (BADD) -------------------------- ------------------------------------------------------------------------- */ private double CalcularBADD(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu, amax, suma1, suma2; int r, contador, j, posicion, repetido; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (int i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; suma1 = 0.0; suma2 = 0.0; /* Look for the set of value to be added for the class "clase" */ while (r < base_reglas.n_reglas) { for (int i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; suma1 += Math.pow(comp, frm.p + 1); suma2 += Math.pow(comp, frm.p); } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma1 += Math.pow(comp, frm.p + 1); suma2 += Math.pow(comp, frm.p); } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; suma1 += Math.pow(comp, frm.p + 1); suma2 += Math.pow(comp, frm.p); } } } r++; } if (contador == 0) { return (0); } else { resu = suma1 / suma2; return (resu); } } /* --------------------------------------------------------------------------- */ private void BuscarMejorClaseBADD(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] badd = new double[tabla.nClasses]; int i, pos, repetido; for (i = 0; i < tabla.nClasses; i++) { badd[i] = CalcularBADD(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(badd, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = badd[pos]; mejor_regla = -2; } else { mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /* ------------------------------------------------------------------------- ----------------------- FRM 9 (Quasiarithmetic Mean) -------------------------- ------------------------------------------------------------------------- */ private double CalcularQUASIARIT(int clase, double[] ejemplo) { double[] A = new double[base_reglas.n_reglas]; double comp, resu; int r, contador, j, posicion, repetido, i; int n_inputs = ejemplo.length - 1; FuzzySet[] D = new FuzzySet[n_inputs]; for (i = 0; i < n_inputs; i++) { D[i] = new FuzzySet(); } r = 0; contador = 0; /* Look for the set of value to be added for the class "clase" */ while (r < base_reglas.n_reglas) { for (i = 0; i < tabla.n_inputs; i++) { D[i] = base_reglas.BaseReglas[r][i]; } switch (tipo_reglas) { case 1: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); if (comp > 0.0) { A[contador] = comp; contador++; } } break; case 2: if (base_reglas.Consecuentes[r][0].clase == clase) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][0].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; } } break; case 3: if (base_reglas.Consecuentes[r][clase].gcerteza > 0.0) { comp = MatchingDegree(ejemplo, D); comp = comp * base_reglas.Consecuentes[r][clase].gcerteza; if (comp > 0.0) { A[contador] = comp; contador++; } } } r++; } if (contador == 0) { return (0); } /* Obtaining the weights */ double[] w = new double[contador]; for (i = 0; i < contador; i++) { w[i] = 1 / ((double) contador); } /* Calculation of the final value for quasiarithmetic mean */ for (i = 0; i < contador; i++) { A[i] = Math.pow(A[i], frm.p); } resu = SumaPonderada(A, w, contador); resu = Math.pow(resu, 1 / frm.p); return (resu); } /* --------------------------------------------------------------------------- */ private void BuscarMejorClaseQUASIARIT(ArrayList < int[] > milista1, ArrayList < double[] > milista2, double[] ejemplo) { int[] auxiliar1 = new int[2]; double[] auxiliar2 = new double[1]; auxiliar1 = milista1.get(0); int mejor_clase = auxiliar1[0]; int mejor_regla = auxiliar1[1]; auxiliar2 = milista2.get(0); double compatib = auxiliar2[0]; double[] quasiarit = new double[tabla.nClasses]; int i, pos, repetido; for (i = 0; i < tabla.nClasses; i++) { quasiarit[i] = CalcularQUASIARIT(i, ejemplo); } ArrayList<int[]> lista1 = new ArrayList<int[]>(1); int[] auxiliar = new int[1]; repetido = 0; auxiliar[0] = repetido; lista1.add(0, auxiliar); pos = MayorD(quasiarit, tabla.nClasses, lista1); auxiliar = lista1.get(0); repetido = auxiliar[0]; if (pos != -1) { mejor_clase = pos; compatib = quasiarit[pos]; mejor_regla = -2; } else { /* example not classified */ mejor_clase = -1; compatib = 0.0; mejor_regla = -2; } auxiliar1[0] = mejor_clase; auxiliar1[1] = mejor_regla; milista1.add(0, auxiliar1); auxiliar2[0] = compatib; milista2.add(0, auxiliar2); } /** * <p> * Returns the rule's fitness * <p> * @param indiv Structure The invididual representing the rule * @return double The fitness value */ public double eval(Structure indiv) { double fitness; /* We calculate the fitness through the tree penality criteria */ RulesCriteria(indiv); fitness = F * G * g; return (fitness); } /** * <p> * Returns the matching degree between an examples and the fuzzy sets * </p> * @param ejemplo double [] The given example * @param D FuzzySet[] The fuzzy sets * @return double The matching degree */ public double MatchingDegree(double[] ejemplo, FuzzySet[] D) { double result = 0.0; switch (compa) { case 0: result = CompatibilidadMinimo(ejemplo, D); break; case 1: result = CompatibilidadProducto(ejemplo, D); break; case 2: result = CompatibilidadMedia(ejemplo, D); break; case 3: result = CompatibilidadMedia2(ejemplo, D); } return (result); } private double CompatibilidadMinimo(double[] ejemplo, FuzzySet[] D) { double minimo, grado_pertenencia; int i; minimo = 1.0; for (i = 0; i < tabla.n_inputs; i++) { grado_pertenencia = base_reglas.Fuzzification(ejemplo[i], D[i]); if (grado_pertenencia < minimo) { minimo = grado_pertenencia; } } return (minimo); } private double CompatibilidadProducto(double[] ejemplo, FuzzySet[] D) { double producto, grado_pertenencia; int i; producto = 1.0; for (i = 0; i < tabla.n_inputs; i++) { grado_pertenencia = base_reglas.Fuzzification(ejemplo[i], D[i]); producto = producto * grado_pertenencia; } return (producto); } private double CompatibilidadMedia(double[] ejemplo, FuzzySet[] D) { double media, grado_pertenencia; int i; media = 0.0; for (i = 0; i < tabla.n_inputs; i++) { grado_pertenencia = base_reglas.Fuzzification(ejemplo[i], D[i]); media += grado_pertenencia; } media = media / tabla.n_inputs; return (media); } private double CompatibilidadMedia2(double[] ejemplo, FuzzySet[] D) { double media, grado_pertenencia; int i, etiqueta, nulo; nulo = 0; media = 0.0; for (i = 0; i < tabla.n_inputs; i++) { grado_pertenencia = base_reglas.Fuzzification(ejemplo[i], D[i]); if (grado_pertenencia == 0.0) { nulo = 1; } media += grado_pertenencia; } if (nulo == 1) { return (0.0); } else { media = media / tabla.n_inputs; return (media); } } /** * <p> * Returns the data for creating the KEEL output file * </p> * @param tabla_datos MyDataset The set of examples * @return String The data for creatring the KEEL output file */ public String ObligatoryOutputFile(MyDataset tabla_datos) { int j; int clase; String salida; salida = "@data\n"; for (j = 0; j < tabla_datos.long_tabla; j++) { clase = Clasification(tabla_datos, j); if(clase == -1){ salida += // (int) (tabla_datos.datos[j]).ejemplo[tabla_datos.n_inputs]) + // " " + clase + " " + "\n"; tabla_datos.getOutputAsString(j) + " ?\n"; } else{ salida += // (int) (tabla_datos.datos[j]).ejemplo[tabla_datos.n_inputs]) + // " " + clase + " " + "\n"; tabla_datos.getOutputAsString(j) + " " + tabla_datos.getClassAsString(clase) + " " + "\n"; } } salida = salida.substring(0, salida.length() - 1); return (salida); } }