/*********************************************************************** 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.Decision_Trees.DT_GA; /** * @author * @version 1.0 */ import java.util.ArrayList; import java.util.StringTokenizer; public class BaseR { ArrayList<Regla> baseReglas; myDataset train; int umbralS; public BaseR() { baseReglas = new ArrayList<Regla> (); } /** * Obtengo la base de reglas a traves del fichero de reglas (extraido a partir del arbol de decision) * @param reglas String * @param train myDataset conjunto de datos de entrenamiento */ public BaseR(myDataset train, String reglas) { baseReglas = new ArrayList<Regla> (); this.train = train; StringTokenizer tokens = new StringTokenizer(reglas, "\n"); while (tokens.hasMoreTokens()) { String regla = tokens.nextToken(); //System.err.println("Regla -> "+regla); Regla r = new Regla(train, regla); baseReglas.add(r); } } public BaseR genetico(int type, int S, int nGenerations, int popSize, double crossProb, double mutProb) { BaseR br = new BaseR(); br.train = this.train; this.umbralS = S; boolean hacerLarge = false; boolean[] ejemplosTr = new boolean[train.size()]; //ejemplos para GA-Large for (int i = 0; i < ejemplosTr.length; i++) { ejemplosTr[i] = false; } //Por si si, o por si no, calculo el accuracy normalizado para cada atributo double [] norm_acc = calculaAccuracy(); for (int i = 0; i < baseReglas.size(); i++) { if (baseReglas.get(i).cubiertos() < S) { if (type == DT_GA.GA_SMALL) { for (int k = 0; k < train.getnClasses(); k++){ ArrayList<Regla> reglas = new ArrayList<Regla> (); Poblacion p = new Poblacion(i, baseReglas.get(i).copia(), nGenerations, popSize, crossProb, mutProb, train, train.nombreClase(k)); p.GA_Small(); reglas = p.dameReglas(); for (int j = 0; j < reglas.size(); j++) { br.baseReglas.add(reglas.get(j).copia()); } } } else { hacerLarge = true; int[] cubiertos = baseReglas.get(i).ejemplosCubiertos.clone(); int nCubiertos = baseReglas.get(i).cubiertos(); for (int j = 0; j < nCubiertos; j++) { ejemplosTr[cubiertos[j]] = true; } } } } if (hacerLarge) { ArrayList<Regla> reglas = new ArrayList<Regla> (); Poblacion p = new Poblacion(ejemplosTr, nGenerations, popSize, crossProb, mutProb, train, norm_acc); p.GA_Large(); reglas = p.dameReglas(); for (int j = 0; j < reglas.size(); j++) { br.baseReglas.add(reglas.get(j).copia()); } } return br; } public String printString() { String cadena = new String(""); cadena += "Number of Rules: " + baseReglas.size() + "\n"; for (int i = 0; i < baseReglas.size(); i++) { cadena += "Rule[" + (i + 1) + "]: " + baseReglas.get(i).printString(); } return cadena; } public int size() { return baseReglas.size(); } /** * Detecta las reglas que cubren un small-disjunt */ public void cubrirEjemplos() { for (int i = 0; i < this.size(); i++) { baseReglas.get(i).cubrirEjemplos(); } } /** * Clasifica un ejemplo * @param tree true si la regla es de tipo "arbol", false si es de tipo "GA" * @param ejemplo double[] el ejemplo a clasificar (valores de los atributos de entrada) * @param clase_ StringBuffer el valor de la clase que se va a devolver * @return boolean true si la regla que lo clasifica pertence a un small disjunct */ public boolean clasifica(boolean tree, double [] ejemplo, StringBuffer clase_){ boolean smallDisjunct = false; String clase = "<unclassified>"; if (tree){ int i; for (i = 0; (i < size()) && (clase.equals("<unclassified>")); i++) { if (baseReglas.get(i).cubre(ejemplo)) { clase = baseReglas.get(i).clase; } } i--; //suma uno al salir smallDisjunct = (baseReglas.get(i).cubiertos() < umbralS); }else{ int i; double pesoMax = 0.0; String claseAux; for (i = 0; i < size(); i++) { //System.err.print(baseReglas.get(i).printString()); if (baseReglas.get(i).cubre(ejemplo)) { claseAux = baseReglas.get(i).clase; double peso = baseReglas.get(i).fitness; if (peso > pesoMax){ clase = claseAux; pesoMax = peso; } } } //System.err.println("Predicho -> "+clase); } clase_.append(clase); return smallDisjunct; } private double [] calculaAccuracy(){ int atts = train.getnInputs(); double [] acc = new double[atts]; int attsNoUsados = 0; boolean [] noUsado = new boolean[atts]; double minAcc = 1.0; int [] clasificados = new int[atts]; int [] correctamenteClas = new int[atts]; for(int i = 0; i < atts; i++){ boolean aparece = false; for (int j = 0; j < this.size(); j++){ //Compruebo en cuantos caminos esta el atributo "i" if (baseReglas.get(j).contieneAtributo(i)){ clasificados[i] += baseReglas.get(j).cubiertos(); correctamenteClas[i] += baseReglas.get(j).cubiertosOK(); aparece = true; } } noUsado[i] = !aparece; if (!aparece){ attsNoUsados++; }else{ acc[i] = 1.0* correctamenteClas[i] / clasificados[i]; if (acc[i] < minAcc){ minAcc = acc[i]; } } } double totalAcc = 0.0; for (int i = 0; i < atts; i++){ if (noUsado[i]){ //si no esta usado acc[i] = minAcc / attsNoUsados; } totalAcc += acc[i]; } for (int i = 0; i < atts; i++){ acc[i] /= totalAcc; //normalizar //System.out.println("Accuracy["+i+"] = "+acc[i]); } return acc; } }