/*********************************************************************** 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.RE_SL_Methods.mogulHC; class Adap { public static double omega, K; public double[] grado_pertenencia; public double[] puntos; public double F, G, g, PC; public int EmparejaAnt; public double EC, EL; public int tipo_fitness, tipo_nichos; public MiDataset tabla, tabla_tst; public BaseR base_reglas; public Adap(MiDataset training, BaseR base, double valor_omega, double valor_k, int fitness, int nichos) { tabla = training; base_reglas = base; omega = valor_omega; K = valor_k; tipo_fitness = fitness; tipo_nichos = nichos; puntos = new double[tabla.n_variables]; grado_pertenencia = new double[tabla.n_variables]; } public static double Minimo(double x, double y) { if (x < y) { return (x); } else { return (y); } } public static double Maximo(double x, double y) { if (x > y) { return (x); } else { return (y); } } /* ------------------------------------------------------------------------- FUNCION FITNESS ------------------------------------------------------------------------- */ /* ------------------------- Criterios de reglas -------------------------- */ /* Calcula el grado de compatibilidad (Ri(ek)) de la regla con el ejemplo */ public double ReglaCubreEjemplo(double[] cromosoma, double[] ejem) { int i, pos_etiq; double minimo_ant, minimo_con; Difuso D = new Difuso(); EmparejaAnt = 0; for (i = 0; i < tabla.n_variables; i++) { pos_etiq = tabla.n_variables + 3 * i; D.x0 = cromosoma[pos_etiq]; D.x1 = cromosoma[pos_etiq + 1]; D.x2 = D.x1; D.x3 = cromosoma[pos_etiq + 2]; D.y = 1; grado_pertenencia[i] = base_reglas.Fuzzifica(ejem[i], D); } minimo_ant = 1; minimo_con = 1; for (i = 0; i < tabla.n_var_estado; i++) { if (grado_pertenencia[i] < minimo_ant) { minimo_ant = grado_pertenencia[i]; } } if (minimo_ant > 0) { EmparejaAnt = 1; } for (i = tabla.n_var_estado; i < tabla.n_variables; i++) { if (grado_pertenencia[i] < minimo_con) { minimo_con = grado_pertenencia[i]; } } return (Minimo(minimo_ant, minimo_con)); } public void CriteriosReglas(double[] cromosoma) { /* Calculo de tres de los criterios de reglas empleados: - frecuencia de una regla [Her95] - grado de cubrimiento medio de ejemplos positivos [Her95] - penalizacion sobre los ejemplos negativos [Gon95] - penalizacion por sobreaprendizaje de ejemplos */ 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; /* Contabilizacion de la frecuencia total de cubrimiento, los ejemplos positivos y los negativos */ for (i = 0; i < tabla.long_tabla; i++) { RCE = ReglaCubreEjemplo(cromosoma, tabla.datos[i].ejemplo); if (tabla.datos[i].cubierto == 0) { frec_acumulada += RCE; if (RCE >= omega) /* Si el ejemplo esta cubierto en el grado deseado */ { /* omega, entonces se considera positivo */ n_ejem_pos++; SumaRCEpositivos += RCE; } } if (RCE == 0.0 && EmparejaAnt > 0) /* Si estan cubiertas las entradas pero no las */ { n_ejem_neg++; /* salidas, entonces es un ejemplo negativo. Estos */ } } /* son determinados sobre todos los ejemplos. */ /* Calculo de la frecuencia de una regla [Her95] */ F = frec_acumulada / tabla.no_cubiertos; /* Calculo del grado de cubrimiento medio de ejemplos positivos [Her95] */ if (n_ejem_pos > 0) { G = SumaRCEpositivos / (double) n_ejem_pos; } else { G = 0.0; } /* Calculo de la penalizacion sobre los ejemplos negativos [Gon95] */ umbral = K * n_ejem_pos; /* Si el numero de negativos es menor o igual que el umbral, entonces no hay penalizacion*/ if (n_ejem_neg <= umbral) { g = 1.0; } else { g = 1.0 / (n_ejem_neg - umbral + Math.exp(1.0)); } /* Si es necesario, se calcula la penalizacion de sobreaprendizaje de ejemplos */ if (tipo_fitness == 2) { n_ejem_ya_cub = 0; for (i = 0; i < tabla.long_tabla; i++) { RCE = ReglaCubreEjemplo(cromosoma, tabla.datos[i].ejemplo); /* Si el ejemplo ya estaba cubierto y la regla actual lo vuelve a cubrir se contabiliza para penalizar */ if (tabla.datos[i].cubierto > 0 && RCE != 0) { n_ejem_ya_cub++; } /* Se efectua la penalizacion correpondiente */ if (n_ejem_ya_cub <= umbral) { PC = 1.0; } else { PC = 1.0 / (n_ejem_ya_cub - umbral + Math.exp(1.0)); } } } } /* --------------- Criterios especificos de la aplicacion ----------------- */ /* Errores Cuadratico y Lineal */ public void Error_tra() { int j; double suma1, suma2, fuerza; for (j = 0, suma1 = suma2 = 0.0; j < tabla.long_tabla; j++) { fuerza = base_reglas.FLC(tabla.datos[j].ejemplo); suma1 += Math.pow(tabla.datos[j].ejemplo[tabla.n_var_estado] - fuerza, 2.0); suma2 += Math.abs(tabla.datos[j].ejemplo[tabla.n_var_estado] - fuerza); } EC = suma1 / (double) tabla.long_tabla; EL = suma2 / (double) tabla.long_tabla; } /* Errores Cuadratico y Lineal TEST */ public void Error_tst(MiDataset tabla_tst) { int j; double suma1, suma2, fuerza; for (j = 0, suma1 = suma2 = 0.0; j < tabla_tst.long_tabla; j++) { fuerza = base_reglas.FLC(tabla_tst.datos[j].ejemplo); suma1 += Math.pow(tabla_tst.datos[j].ejemplo[tabla_tst.n_var_estado] - fuerza, 2.0); suma2 += Math.abs(tabla_tst.datos[j].ejemplo[tabla_tst.n_var_estado] - fuerza); } EC = suma1 / (double) tabla_tst.long_tabla; EL = suma2 / (double) tabla_tst.long_tabla; } /* ---------------------------- Funcion fitness --------------------------- */ public double eval(double[] cromosoma) { if (tipo_fitness == 1) { return (eval_mulmodal(cromosoma)); } else { return (eval_criterios(cromosoma)); } } /* Fitness para el niching secuencial. La penalizacion del sobreaprendizaje se implementa con la penalizacion del algoritmo multimodal */ public double eval_mulmodal(double[] cromosoma) { double fitness; /* Se calcula la adecuacion de la regla codificada en el cromosoma actual, se estudia la posible penalizacion del mismo y se devuelve el valor final */ CriteriosReglas(cromosoma); fitness = F * G * g * LNIR(cromosoma); return (fitness); } /* La penalizacion del sobreaprendizaje se implementa segun un criterio de reglas */ public double eval_criterios(double[] cromosoma) { double fitness; /* Se calcula la adecuacion de la regla codificada en el cromosoma actual, se estudia la posible penalizacion del mismo y se devuelve el valor final */ CriteriosReglas(cromosoma); fitness = F * G * g * PC; return (fitness); } /* ------------------------------------------------------------------------- Funciones de calculo del Ratio de Interaccion ------------------------------------------------------------------------- */ /* Penalizacion debil: Penaliza la regla codificada en el cromosoma cuanto mas se acerque a los centros de las reglas anteriormente aprendidas (almacena dos en ListaTabu) */ public double NIR1(double[] cromosoma) { int i; double cubr_act, max_cubr; /* Se obtiene el maximo grado en que la regla codificada en cromosoma cubre a los centros de las reglas anteriores (medida de proximidad de la regla actual a las anteriores aprendidas) */ max_cubr = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { cubr_act = ReglaCubreEjemplo(cromosoma, base_reglas.ListaTabu[i]); if (cubr_act > max_cubr) { max_cubr = cubr_act; } } return (max_cubr); } /* Penalizacion media 1: Penaliza la regla codificada en el cromosoma cuanto mas toque tanto los centros como el soporte de las reglas anteriormente aprendidas */ public double NIR2(double[] cromosoma) { int i, j; double[] cubr_act = new double[3]; double max_cubr; /* Se obtiene el maximo grado en que la regla codificada en cromosoma cubre a los centros y los soportes de las reglas anteriores (medida de proximidad de la regla actual a las anteriores aprendidas) */ max_cubr = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { /* Punto izquierdo */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x0; } cubr_act[0] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[0] > max_cubr) { max_cubr = cubr_act[0]; } /* Centro */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x1; } cubr_act[1] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[1] > max_cubr) { max_cubr = cubr_act[1]; } /* Punto derecho */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x3; } cubr_act[2] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[2] > max_cubr) { max_cubr = cubr_act[2]; } } return (max_cubr); } /* Penalizacion media 2: Penaliza la regla codificada en el cromosoma cuanto mas se acerque a los centros de las reglas anteriormente aprendidas (alma- cenados en ListaTabu) y cuanto mas se acerquen las otras al centro de esta */ public double NIR3(double[] cromosoma) { int i, j; double cubr_act, max_cubr_otras, max_cubr_nueva, grado_pertenencia; /* Se obtiene el maximo grado en que la regla codificada en cromosoma cubre a los centros de las reglas anteriores (medida de proximidad de la regla actual a las anteriores aprendidas) */ max_cubr_otras = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { cubr_act = ReglaCubreEjemplo(cromosoma, base_reglas.ListaTabu[i]); if (cubr_act > max_cubr_otras) { max_cubr_otras = cubr_act; } } /* Se obtiene el maximo grado en que las reglas ya aprendidas cubren a la codificada en el cromosoma (medida de proximidad de las reglas anterior- mente aprendida a la actual) */ max_cubr_nueva = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { cubr_act = 1.0; for (j = 0; j < tabla.n_variables; j++) { grado_pertenencia = base_reglas.Fuzzifica(cromosoma[tabla.n_variables + (3 * j) + 1], base_reglas.BaseReglas[i][j]); if (grado_pertenencia < cubr_act) { cubr_act = grado_pertenencia; } } if (cubr_act > max_cubr_nueva) { max_cubr_nueva = cubr_act; } } return (Adap.Maximo(max_cubr_otras, max_cubr_nueva)); } /* Penalizacion fuerte: Penaliza la regla codificada en el cromosoma cuanto mas toque tanto los centros como el soporte de las reglas anteriormente aprendidas y cuanto mas toquen las otras el centro y el soporte de esta */ public double NIR4(double[] cromosoma) { int i, j; double[] cubr_act = new double[3]; double max_cubr_otras, max_cubr_nueva, grado_pertenencia; /* Se obtiene el maximo grado en que la regla codificada en cromosoma cubre a los centros y los soportes de las reglas anteriores (medida de proximidad de la regla actual a las anteriores aprendidas) */ max_cubr_nueva = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { /* Punto izquierdo */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x0; } cubr_act[0] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[0] > max_cubr_nueva) { max_cubr_nueva = cubr_act[0]; } /* Centro */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x1; } cubr_act[1] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[1] > max_cubr_nueva) { max_cubr_nueva = cubr_act[1]; } /* Punto derecho */ for (j = 0; j < tabla.n_variables; j++) { puntos[j] = base_reglas.BaseReglas[i][j].x3; } cubr_act[2] = ReglaCubreEjemplo(cromosoma, puntos); if (cubr_act[2] > max_cubr_nueva) { max_cubr_nueva = cubr_act[2]; } } /* Se obtiene el maximo grado en que las reglas ya aprendidas cubren el soporte y los centros de la codificada en el cromosoma (medida de proxi- midad de las reglas anteriormente aprendida a la actual) */ max_cubr_otras = (double) 0.0; for (i = 0; i < base_reglas.n_reglas; i++) { cubr_act[0] = cubr_act[1] = cubr_act[2] = 1.0; for (j = 0; j < tabla.n_variables; j++) { /* Punto izquierdo */ grado_pertenencia = base_reglas.Fuzzifica(cromosoma[tabla.n_variables + (3 * j)], base_reglas.BaseReglas[i][j]); if (grado_pertenencia < cubr_act[0]) { cubr_act[0] = grado_pertenencia; } /* Centro */ grado_pertenencia = base_reglas.Fuzzifica(cromosoma[tabla.n_variables + (3 * j) + 1], base_reglas.BaseReglas[i][j]); if (grado_pertenencia < cubr_act[1]) { cubr_act[1] = grado_pertenencia; } /* Punto derecho */ grado_pertenencia = base_reglas.Fuzzifica(cromosoma[tabla.n_variables + (3 * j) + 2], base_reglas.BaseReglas[i][j]); if (grado_pertenencia < cubr_act[2]) { cubr_act[2] = grado_pertenencia; } } if (cubr_act[0] > max_cubr_otras) { max_cubr_otras = cubr_act[0]; } if (cubr_act[1] > max_cubr_otras) { max_cubr_otras = cubr_act[1]; } if (cubr_act[2] > max_cubr_otras) { max_cubr_otras = cubr_act[2]; } } return (Adap.Maximo(max_cubr_otras, max_cubr_nueva)); } /* ------------------------------------------------------------------------- Criterio de penalizacion del Ratio de Interaccion ------------------------------------------------------------------------- */ /* Se penaliza en funcion de la interaccion existente entre la regla actual y las anteriores. Cuanto menor sea dicha interaccion, menos penalizada es la regla (LNIR -> 1). Cuanto mayor sea, mas penalizada es (LNIR -> 0) */ public double LNIR(double[] cromosoma) { double salida = 1; switch (tipo_nichos) { case 1: salida = 1 - NIR1(cromosoma); break; case 2: salida = 1 - NIR2(cromosoma); break; case 3: salida = 1 - NIR3(cromosoma); break; case 4: salida = 1 - NIR4(cromosoma); break; } return (salida); } /* ------------------------------------------------------------------------- Funciones comunes ------------------------------------------------------------------------- */ /* salida */ public String getSalidaObli(MiDataset tabla_datos) { int j; double fuerza; String salida; salida = "@data\n"; for (j = 0; j < tabla_datos.long_tabla; j++) { fuerza = base_reglas.FLC(tabla_datos.datos[j].ejemplo); salida += (tabla_datos.datos[j]).ejemplo[tabla_datos.n_var_estado] + " " + fuerza + " " + "\n"; } salida = salida.substring(0, salida.length() - 1); return (salida); } }