/*********************************************************************** 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.Genetic_Rule_Learning.SIA; /** * <p>Title: Evaluation of the quality of the rules</p> * <p>Description: This class computes the final statistics </p> * @author Written by Jos� Ram�n Cano de Amo (University of Ja�n) 08/04/2004 * @author Modified by Alberto Fern�ndez (University of Granada) 02/17/2005 * @version 1.3 * @since JDK1.4 */ public class evaluateRuleQuality { private int nClases; private double aciertoTst; private double aciertoTrn; private ruleSet ruleSet; private double [][] bounds; private int [] lims; private int [] tipos; private String [] nombreClases; /** * Class Builder * @param conjreg Final rule set * @param numClases Number of classes of the problem * @param rangs Bounds array * @param limites Array with the length of the bounds array * @param tips Array with the types of the attributes * @param _nombreClases String [] names of the data-set classes */ public evaluateRuleQuality(ruleSet conjreg, int numClases,double [][] rangs,int [] limites, int [] tips, String [] _nombreClases) { ruleSet = conjreg; nClases = numClases; bounds = rangs; lims = limites; tipos = tips; nombreClases = _nombreClases; } /** * Function that computes the distance from the rule to the example (for classification) * @param r The rule * @param m The example * @return A distance measure (between 0 and 1) that determines what next is the rule to * the example (the less the value, the better the approximation) */ private double calculaDistancia(Rule r, Instance m) { double d = 0, dist = 0; int n_de_r = 0; double atts[] = m.getMuest(); for (int i = 0; i < m.getNattributes(); i++) { Condition c = r.getCondition(i); if (c.getType() == 0) { dist = 0; } else { n_de_r++; //There are one more condition that is not from type * if (Double.isNaN(atts[i])){ dist = 1; } else{ switch (tipos[i]) { case 3: case 4: //Real or integer double inf = c.getLowerBound(); double sup = c.getUpperBound(); if ( (atts[i] >= inf) && (atts[i] <= sup)) { dist = 0; } else { if (atts[i] < inf) { dist = (atts[i] - inf) / (bounds[i][0] - bounds[i][lims[i] - 1]); } else { dist = (sup - atts[i]) / (bounds[i][0] - bounds[i][lims[i] - 1]); } } if (dist > 1) { //Normalization dist = 1; } break; case 2: if (c.getValue() == atts[i]) { dist = 0; } else { dist = 1; } break; } } } dist *= dist; //dist^2 d += dist; //sum(di^2) } d = Math.sqrt(d); d /= n_de_r; return d; } /** * It generates a string with the ouput list, <expected output> <method output> * @param datos Data-set * @param entrena 0 if it refer to the training set, 1 for test set * @return A string with a list of pair values <original class> <computed class> */ public String salida(myDataset datos,int entrena) { String cadena = new String(""); int voto[] = new int[nClases]; double [] distancias = new double[ruleSet.size()]; int [] minimas = new int[ruleSet.size()]; int numero = 0; double dmin; double fmax; int j, cl, max,aciertos = 0; for (int i = 0; i < datos.size(); i++) { for (j = 0; j < nClases; j++) { voto[j] = 0; } for (j = 0; j < ruleSet.size(); j++) { // rules that verify the instance distancias[j] = calculaDistancia(ruleSet.getRule(j),datos.getData(i)); } numero = 0; dmin = Double.MAX_VALUE; for (j = 0; j < ruleSet.size(); j++) { if (distancias[j] < dmin){ dmin = distancias[j]; //Updates the minimum distance numero = 1; //Number of rules with d_min minimas[numero-1] = j; //Position of the rules } else{ if (distancias[j] == dmin) { numero++; minimas[numero - 1] = j; } } } fmax = Double.MIN_VALUE; for (j = 0; j < numero; j++){ if ((ruleSet.getRule(minimas[j])).getStrength() > fmax){ fmax = (ruleSet.getRule(minimas[j])).getStrength(); voto[ruleSet.getRule(minimas[j]).getClas()]++; } } for (j = 0, max = -1, cl = 0; j < nClases; j++) { //Obtains the class if (voto[j] > max) { max = voto[j]; cl = j; } } cadena += new String(nombreClases[datos.getData(i).getClas()] + " " + nombreClases[cl] + "\n"); if (cl == datos.getData(i).getClas()) { aciertos++; } } if (entrena == 0) aciertoTrn = (double) aciertos / datos.size(); else aciertoTst = (double) aciertos / datos.size(); return cadena; } /** * It returns a string with the accuracy percentage in training and test * @return a string with the accuracy percentage in training and test */ public String printString(){ String cad = ""; cad += "@Accuracy in Training: "+aciertoTrn; cad += "\n@Accuracy in Test: "+aciertoTst; return cad; } }