/*********************************************************************** 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.ImbalancedClassification.Ensembles; import java.util.ArrayList; import java.util.StringTokenizer; /** * <p>Title: Rule</p> * <p>Description: Rule representation * <p>Company: KEEL </p> * @author Alberto Fernandez (University of Jaen) 09/10/2012 * @version 1.1 * @since JDK1.6 */ public class Rule { ArrayList<Selector> antecedent; String clase; myDataset train; int coveredExamples[]; int positiveCoveredEx[]; int nCubiertos,nCubiertosOK; //number of covered examples float fCubiertos, fCubiertosOK; double fitness; //si es una Rule producida por el GA int codigoRule; //si es una Rule producida por el GA /** * Default constructor */ public Rule() { antecedent = new ArrayList<Selector> (); coveredExamples = new int[1]; } /** * Constructor with parameters. It initializes a rule for a given class * @param clase class value * @param train training set */ public Rule(String clase, myDataset train) { antecedent = new ArrayList<Selector> (); this.train = train; this.clase = clase; coveredExamples = new int[train.size()]; positiveCoveredEx = new int[train.size()]; } /** * Constructor with parameters. It initializes a rule from a C4.5 file of rules (just a single line) * @param train training set * @param linea Line of the file which stores the C4.5 rule set */ public Rule(myDataset train, String linea) { antecedent = new ArrayList<Selector> (); this.train = train; coveredExamples = new int[train.size()]; positiveCoveredEx = new int[train.size()]; String [] nombres = train.nombres(); StringTokenizer campo = new StringTokenizer(linea, " "); campo.nextToken(); //RULE-X: String aux = campo.nextToken(); //IF while(!aux.equalsIgnoreCase("THEN")){ String atributo = campo.nextToken(); String operador = campo.nextToken(); String valor = campo.nextToken(); Selector s = new Selector(atributo,operador,valor); s.adjuntaNombres(nombres); antecedent.add(s); aux = campo.nextToken(); } campo.nextToken(); //class campo.nextToken(); //= clase = campo.nextToken(); } public void incluyeSelector(Selector s) { antecedent.add(s); } public String printString() { String cadena = new String(""); cadena += "IF "; for (int i = 0; i < antecedent.size()-1; i++) { cadena += antecedent.get(i).printString()+ "AND "; } cadena += antecedent.get(antecedent.size()-1).printString(); cadena += " THEN Class = " + clase + " ("+nCubiertosOK+"/"+nCubiertos+")\n"; return cadena; } public String printStringF() { String cadena = new String(""); cadena += "IF "; for (int i = 0; i < antecedent.size()-1; i++) { cadena += antecedent.get(i).printString()+ "AND "; } if (antecedent.size() > 0) cadena += antecedent.get(antecedent.size()-1).printString(); cadena += " THEN Class = " + clase + " ("+fCubiertosOK+"/"+fCubiertos+")\n"; return cadena; } /** * Creates a copy of a rule * @return a new copy of the rule */ public Rule copy(){ Rule r = new Rule(clase, train); r.antecedent = new ArrayList<Selector>(); for (int i = 0; i < antecedent.size(); i++){ r.antecedent.add(antecedent.get(i).copy()); } r.nCubiertos = nCubiertos; r.nCubiertosOK = nCubiertosOK; r.coveredExamples = new int[coveredExamples.length]; r.coveredExamples = coveredExamples.clone(); r.positiveCoveredEx = new int[positiveCoveredEx.length]; r.positiveCoveredEx = positiveCoveredEx.clone(); r.fitness = fitness; r.codigoRule = codigoRule; return r; } public int covered(){ return nCubiertos; } public int positiveCovered(){ return nCubiertosOK; } /** * It counts how many examples are covered and also how many of them are positive */ public void coverExamples(){ nCubiertos = nCubiertosOK = 0; for (int i = 0; i < train.size(); i++){ double [] ejemplo = train.getExample(i); if (this.covers(ejemplo)){ coveredExamples[nCubiertos] = i; nCubiertos++; if (train.getOutputAsString(i).compareToIgnoreCase(this.clase) == 0){ positiveCoveredEx[nCubiertosOK] = i; nCubiertosOK++; } } } } /** * It checks the weights of the covered examples * @param weights the weights of all examples */ public void coverExamples(double[] weights){ fCubiertos = fCubiertosOK = 0; for (int i = 0; i < train.size(); i++){ double [] ejemplo = train.getExample(i); if (this.covers(ejemplo)){ fCubiertos += weights[i]; if (train.getOutputAsString(i).compareToIgnoreCase(this.clase) == 0){ fCubiertosOK += weights[i]; } } } train = null; coveredExamples = null; positiveCoveredEx = null; } /** * To compute whether the rule covers an example * @param example * @return True if the rule covers the example. False otherwise. */ public boolean covers(double [] example){ boolean cubierto = true; for (int i = 0; (i < antecedent.size())&&(cubierto); i++){ cubierto = cubierto && (antecedent.get(i).covers(example)); } return cubierto; } public int size(){ return antecedent.size(); } public boolean contieneAtributo(int att){ boolean contiene = false; for (int i = 0; i < antecedent.size() && !contiene; i++){ contiene = (antecedent.get(i).attribute == att); } return contiene; } }