/*********************************************************************** 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/ **********************************************************************/ /** * <p> * @author Written by Juli�n Luengo Mart�n 14/02/2007 * @version 0.1 * @since JDK 1.5 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.CORE; import java.util.ArrayList; import java.util.Collections; import org.core.Randomize; import keel.Dataset.Attribute; import keel.Dataset.Attributes; import keel.Dataset.InstanceSet; /** * <p> * This class implements the cooperative-competitive rule-based scheme of * the CORE algorithm * </p> */ public class Cochromosome{ int numRules; ArrayList<Chromosome> rules; double fitness; boolean evaluated; int nGenes; int Mu; /** * <p> * default constructor. Allocates new memory for the arrays * </p> */ public Cochromosome(){ rules = new ArrayList<Chromosome>(); numRules = 0; evaluated = false; nGenes = 0; Mu = 0; } /** * <p> * Deep-copy constructor (but the arraylist of chromosomes * only copies the references to the chromosome objects!) * </p> * @param c */ public Cochromosome(Cochromosome c){ numRules = c.numRules; rules = new ArrayList<Chromosome>(c.rules); fitness = c.fitness; evaluated = c.evaluated; nGenes = c.nGenes; Mu = c.Mu; } /** * <p> * Adds a chromosome to this list * </p> * @param c the new chromosome */ public void addChromosome(Chromosome c){ rules.add(c); numRules++; nGenes += c.getNumGenes(); Collections.sort(rules,Collections.reverseOrder()); } /** * <p> * Remove the specified chromosome from this object * </p> * @param c the chromosome to be deleted */ public void removeChromosome(Chromosome c){ rules.remove(c); nGenes-=c.getNumGenes(); numRules--; } /** * <p> * Removes the chromosome at the specified position * </p> * @param c the chromosome to be deleted */ public void removeChromosome(int c){ nGenes-=rules.get(c).getNumGenes(); rules.remove(c); numRules--; } /** * <p> * Test if this cochromosome contains the specified chromosome * </p> * @param c the chromosome we are looking for * @return True if present, false otherwise */ public boolean contains(Chromosome c){ return rules.contains(c); } /** * <p> * Gets the number of rules (chromosomes) * </p> * @return the number of chromosomes in this object */ public int getNumRules(){ return numRules; } /** * <p> * Gets the TOTAL number of genes across all chromosomes in this object * </p> * @return the number of chromosomes */ public int getNumGenes(){ return nGenes; } /** * <p> * Gets the mu parameter * </p> * @return the mu value */ public int getMu(){ return Mu; } /** * <p> * Sets a new mu value * </p> * @param newMu the new mu */ public void setMu(int newMu){ Mu = newMu; } /** * <p> * Evaluates this cochromosome with the provided data set * </p> * @param ISet data set for testing this set of rules * @return the classification accuracy obtained (fitness) */ public double evaluate(InstanceSet ISet){ Chromosome rule; double input[]; int output; int predicted = -1; int wellClassified = 0; if(evaluated) return fitness; for(int k=0;k<ISet.getNumInstances();k++){ input = ISet.getInstance(k).getAllInputValues(); output = (int)ISet.getInstance(k).getAllOutputValues()[0]; predicted = -1; //IMPORTANT!!! the rule vector MUST be sorted by each rule's fitness! for(int i=0;i<rules.size() && predicted == -1;i++){ rule = rules.get(i); predicted = rule.evaluate(input); } //if no class predicted by this rule set, output the majority class of the data set // if(predicted==-1) // predicted = Core.majorityClass; if(predicted==output) wellClassified++; } fitness = (double)wellClassified / (double)ISet.getNumInstances(); evaluated = true; return fitness; } /** * <p> * Gets the evaluation condition * </p> * @return true if it has been evaluated with this set of rules, false otherwise */ public boolean isEvaluated(){ return evaluated; } /** * <p> * Sets the evaluation condition * </p> * @param newEval the new evaluation condition */ public void setEvaluated(boolean newEval){ evaluated = newEval; } /** * <p> * Performs the classification of a data set for final results printing purposes. * Writes the input (known) class and the output (predicted) class in two arrays * (previously created!!) * </p> * @param ISet the reference data set * @param instancesIN the array with size of examples. Will contain the known class labels * @param instancesOUT the array with the predicted class labels * @return the classification accuracy */ public double classify(InstanceSet ISet, String instancesIN[], String instancesOUT[]){ Chromosome rule; double input[]; int output; int predicted = -1; int wellClassified = 0; Attribute a = Attributes.getOutputAttribute(0); int tipo = a.getType(); for(int k=0;k<ISet.getNumInstances();k++){ input = ISet.getInstance(k).getAllInputValues(); output = (int)ISet.getInstance(k).getAllOutputValues()[0]; predicted = -1; //IMPORTANT!!! the rule vector MUST be sorted by each rule's fitness! for(int i=0;i<rules.size() && predicted == -1;i++){ rule = rules.get(i); predicted = rule.evaluate(input); } //if no class predicted by this rule set, output the majority class of the data set if(predicted==-1) predicted = Core.majorityClass; if(predicted==output) wellClassified++; if(tipo!=Attribute.NOMINAL){ instancesIN[k] = new String(String.valueOf(ISet.getInstance(k).getOutputNominalValues(0))); instancesOUT[k] = new String(String.valueOf(predicted)); } else{ instancesIN[k] = new String(ISet.getInstance(k).getOutputNominalValues(0)); instancesOUT[k] = new String(a.getNominalValue(predicted)); } } return (double)wellClassified / (double)ISet.getNumInstances(); } }