/***********************************************************************
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 Albert Orriols (La Salle, Ram�n Llull University - Barcelona) 28/03/2004
* @author Modified by Xavi Sol� (La Salle, Ram�n Llull University - Barcelona) 03/12/2008
* @version 1.1
* @since JDK1.2
* </p>
*/
package keel.Algorithms.Genetic_Rule_Learning.XCS;
import keel.Algorithms.Genetic_Rule_Learning.XCS.KeelParser.Config;
import java.util.*;
import java.lang.*;
import java.io.*;
public class WilsonReduction implements Reduction {
/**
* <p>
* This class implements the reduction Interface. It codifies an strict
* version of the wilson reduction proposed in Wilson 2002.
* </p>
*/
///////////////////////////////////////
// operations
/**
* <p>
* Creates one WilsonReduction Object.
* </p>
*/
public WilsonReduction() {
} // end WilsonReduction
/**
* <p>
* Compacts the ruleSet of the population. Before doing that, it writes
* all the classifiers in a file. Then it compacts the classifiers
* following the method described in Wilson's 2002 article. After all, it
* writes the new ruleset into a file, with the same name and .cmp
* (compacted) extension.
* It does not destroy the environment.
* It does modify the population (it returns the population sorted).
* </p>
* <p>
*
* @return a Population with the reduced population. So, the initial
* population is not modified.
* </p>
* <p>
* @param pop is the population that has to be reduced.
* </p>
* <p>
* @param reductionEnv is the environment that will be used to get the performance
* of classifiers.
* </p>
*/
public Population makeReduction(Population pop, Environment reductionEnv) {
int i=0,j=0;
//First we sort the population.
if (Config.typeOfReduction.toUpperCase().equals("ER"))
// The last parameter: 0 --> Numerosity, 1 --> Experience
pop.sortPopulation(0,pop.getMacroClSum()-1,0);
else
pop.sortPopulation(0,pop.getMacroClSum()-1,1);
//////////////////////////////////////////////////////////////////
//System.out.println ("After sorting the population, it keeps as: ");
//pop.print();
/////////////////////////////////////////////////////////////////
// Now, we look for the performance of the sets of classifiers until we get a 100% performance.
double [] performance = new double [pop.getMacroClSum()];
for (i=0; i<performance.length; i++) performance[i] = 0.;
i=0;
boolean exit = false;
double maxPerf = 0.;
int posMaxPerf = 0;
//System.out.println ("We start to compute the performance of the 'i' first classifiers");
while (i<pop.getMacroClSum() && !exit){
performance[i] = getPerformance(pop,reductionEnv,i);
if (performance[i] > maxPerf){
maxPerf = performance[i];
posMaxPerf = i;
}
System.out.println ("Performance["+i+"] = "+performance[i]);
if (performance[i] == 1.) exit = true;
//We add 1 to i if we have found the 100% performance to get the number of classifiers needed of the position.
i++;
}
if (!exit){
System.out.println ("THE POPULATION HAS NOT REACHED THE 100% PERFORMANCE. THE RULESSET REDUCTION WILL BE MADE WITH "+maxPerf+" PERFORMANCE");
i = posMaxPerf+1;
}
double currentPerf = 0.;
Population BPop = new Population(i); //We create a new population with the maximum size of 'i', the number of classifiers in the set with 100% performance
System.out.println ("The population B of size "+i+" is builded. It is: ");
for (j=0; j<i; j++){
if (currentPerf < performance[j]){
currentPerf = performance[j];
BPop.addClassifier(pop.getClassifier(j));
}
}
BPop.print();
System.out.println ("\n\n The population Mcomp is created");
return BPop.createMCompPopulation(reductionEnv);
} // end makeReduction
/**
* <p>
* Gets the performance of the first classifiers in the population
* applied in the 'n' first classifiers in the population.
* A file environment is needed.
* </p>
* <p>
* @param env is the file environment that contains the input examples.
* </p>
* <p>
* @param n is the number of classifiers in the population that has to
* be considered.
* </p>
* <p>
* @return double with the percentage of correct classifications.
* </p>
*/
private double getPerformance(Population pop,Environment env,int n){
int i=0, j=0;
double []example= null;
int numberOfNoClassified=0, numberOfClassified=0,numberOfCorrectClassifications=0,numberOfWrongClassifications=0;
env.beginSequentialExamples();
for (i=0; i<=n; i++){
pop.getClassifier(i).setNumberMatches(0);
}
for (i=0; i<env.getNumberOfExamples(); i++){
Population matchSet = new Population(pop.getMacroClSum());
if (i==0) example = env.getCurrentState();
else example = env.getSequentialState();
// We add the classifiers of the population that match with this input example
for (j=0; j<=n; j++){
if (pop.getClassifier(j).match (example)){
//set[j].print();
pop.getClassifier(j).increaseNumberMatches(1);
matchSet.addClassifier(pop.getClassifier(j));
}
}
//If there are no classifiers that match with the examples, we increase the numberOfNoClassified.
if (matchSet.getMacroClSum() == 0) numberOfNoClassified ++;
else{ //Else we create the prediction array and look if the prediction is ok.
PredictionArray predArray = new PredictionArray(matchSet);
if (predArray.getBestValue()==0 || predArray.howManyBestActions() > 1){
numberOfNoClassified ++;
}
else{
numberOfClassified ++;
if (predArray.getBestAction() == env.getEnvironmentClass())
numberOfCorrectClassifications++;
else
numberOfWrongClassifications++;
}
}
}
return (double)numberOfCorrectClassifications / (double)env.getNumberOfExamples();
} // end getPerformance
} // end WilsonReduction