/*********************************************************************** 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/ **********************************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package keel.Algorithms.Rule_Learning.LEM1; import java.io.*; import java.util.*; import keel.Dataset.Attribute; import keel.Dataset.Attributes; /** * * @author IDG */ public class BaseReglas { private LinkedList<String> base_de_reglas_salida = new LinkedList<String> (); private LinkedList<TreeMap<Integer,Double>> base_de_reglas = new LinkedList<TreeMap<Integer,Double>>(); private myDataset train; public BaseReglas(LinkedList<Integer> cobertura_global, myDataset atrain){ double [] fila; //variable para almacenar los valores de una fila completa TreeMap<Integer,Double> antecedentes = new TreeMap<Integer,Double> (); train=atrain; int r_aux=0; double v_aux; for (int j=0;j<train.getnData();j++){ //para cada fila antecedentes.clear(); fila = train.getExample(j); //Cogemos la fila completa for (int i=0;i<cobertura_global.size();i++){ //Nos quedamos con el valor de los inputs(columnas) indicados por la cobertura global // Double aux_double = fila[cobertura_global.get(i)]; antecedentes.put(cobertura_global.get(i), fila[cobertura_global.get(i)]); } int i = 0; while(antecedentes.size()>1 && i<antecedentes.size()){ //mientras que en el conjunto haya más de 1, y el índice i sea válido //Borramos, guardando una copia por si luego hay que volverlo a incluir Iterator iter = antecedentes.keySet().iterator(); for(int x=0; x<=i;x++){ r_aux = (Integer) iter.next(); } v_aux = antecedentes.remove(r_aux); //Si cubren diferentes conceptos los antecedentes (no son válidos) if (!valido(antecedentes)){ //Volvemos al estado anterior de R añadiendo lo que habíamos borrado con anterioridad antecedentes.put(r_aux, v_aux); //R.add(i,r_aux); i++; //incrementamos el contador para sacer el siguiente en la próxima pasada } }//Fin del while //En este punto ya tenemos una regla para añadir if (!base_de_reglas.contains(antecedentes)){ //Si el resultado (regla) no está repetido //Añadimos el par columnas-valores base_de_reglas.add((TreeMap<Integer,Double>)antecedentes.clone()); base_de_reglas_salida.add(train.getOutputAsString(j)); } } //Fin del for } private boolean valido(TreeMap<Integer,Double> antecedentes){ boolean valido = true; boolean coincidente; int output = -1; for (int i=0;i<train.getnData();i++){ coincidente = true; Iterator j = antecedentes.keySet().iterator(); while(j.hasNext()){ int aux = (Integer) j.next(); //Comparamos el valor de la Fila i-columna R[j] con el valor de R[j] que tenemos if (train.getExample(i)[aux]!=antecedentes.get(aux)){ coincidente = false; } } if(coincidente){ //Estamos en una fila que coincide con los valores de los inputs que tenemos en R if (output==-1){ //Si es la primera vez que es coincidente output = train.getOutputAsInteger(i); //guardamos la salida }else if(output!=train.getOutputAsInteger(i)){ //Si no, comparamos la salida de la fila actual con la anterior guardada valido = false; //si no coincide, no es valido } } } return valido; } public LinkedList<String> compruebaReglas(myDataset test){ LinkedList<String> resultados = new LinkedList<String>(); double[] fila; boolean valor_bueno = false; //atributo coincide con un antecedente boolean encontrado = false; //regla encontrada for(int j=0;j<test.getnData();j++){ //Para cada fila encontrado = false; fila = test.getExample(j); //cogemos la fila int i=0; while(i<base_de_reglas.size() && !encontrado){//bucle de base de reglas int k=0; int aciertos = 0; while (k<test.getnInputs() && !encontrado){//bucle para las columnas de las tablas valor_bueno = false; Iterator z = base_de_reglas.get(i).keySet().iterator();//iterador sobre las claves de cada Treemap while(z.hasNext() && !encontrado && !valor_bueno){ int valor_atributo = (Integer) z.next();//obtenemos el atributos del antecedente if (valor_atributo == k){//Si el atributo es igual al antecednte //coincide el valor del antecedente y atributo if (fila[k]==base_de_reglas.get(i).get(valor_atributo)){ aciertos++; valor_bueno=true; //para que no compare este mismo valor con otro antecedente //Si se ha cumplido una regla, intorudimos el valor de salida en el la lista if (aciertos==base_de_reglas.get(i).size()){ resultados.add(base_de_reglas_salida.get(i));//add encontrado = true;//regla encontrada, parar la busqueda para la fila } }//La columna está, pero valores distintos }//La columna no esta en el antecedente' } k++; }//fin while k i++; } if (encontrado==false) resultados.add("No clasificado"); //si no encuentra ninguna regla coincidente } return resultados; } public void mostrarReglas(){ //Mostramos la base de reglas: Attribute a[] = Attributes.getInputAttributes(); Attribute s[] = Attributes.getOutputAttributes(); System.out.println("Base de Reglas: \n"); for (int i=0; i<base_de_reglas.size(); i++){ Iterator j = base_de_reglas.get(i).keySet().iterator(); while(j.hasNext()){ int atributo = (Integer) j.next(); int valor = (base_de_reglas.get(i).get(atributo)).intValue(); System.out.print("("+a[atributo].getName()+"," + a[atributo].getNominalValue(valor) +")"); if (j.hasNext()) System.out.print(" & "); } System.out.println(" -> ("+ s[0].getName() +","+base_de_reglas_salida.get(i)+")"); System.out.println("------------------------------------"); } } public void ficheroReglas(String ficheroReglas,String output){ //Mostramos la base de reglas: Attribute a[] = Attributes.getInputAttributes(); Attribute s[] = Attributes.getOutputAttributes(); try { FileOutputStream f = new FileOutputStream(ficheroReglas); DataOutputStream fis = new DataOutputStream((OutputStream) f); output +="BASE DE REGLAS: \n\n"; //Numero de reglas output +="Número de reglas: "+ base_de_reglas.size() + " \n\n"; //Tamaño medio de las reglas obtenidas Double media_reglas = 0.0; for (int i=0; i<base_de_reglas.size(); i++){ Integer aux = base_de_reglas.get(i).size()+1; media_reglas += aux.doubleValue(); } output +="Tamaño medio de las reglas obtenidas: "+ media_reglas/base_de_reglas.size() + " \n\n"; for (int i=0; i<base_de_reglas.size(); i++){ Iterator j = base_de_reglas.get(i).keySet().iterator(); while(j.hasNext()){ int atributo = (Integer) j.next(); output += "(" + a[atributo].getName()+ ",";//almacena atributo Integer valor = (base_de_reglas.get(i).get(atributo)).intValue(); String prueba = a[atributo].getNominalValue(valor); //almacena valor atributo, si prueba==null, guarda el entero, sino la cadena if (prueba == null){ output += valor.toString() + ")"; }else{ output += prueba + ")"; } if (j.hasNext()) output +=" & "; } output +=" -> ("+ s[0].getName() +","+base_de_reglas_salida.get(i)+") \n"; output += "------------------------------------\n"; } fis.writeBytes(output); fis.close(); }catch (IOException e) { e.printStackTrace(); System.exit( -1); } } }