/*********************************************************************** 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 University Ram�n Lull, Barcelona) 28/03/2004 * @author Modified by Xavi Sol� (La Salle University Ram�n Lull, Barcelona) 03/12/2008 * @version 1.2 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.UCS; import java.util.*; import java.lang.*; import java.io.*; public class UCS { /** * <p> * UCS * </p> * * This class controls the UCS run. The core of UCS is a population of classifiers (pop). * Moreover, it has a set of objects to implement the different operators and mechanisms: * environments, GA, prediction array, etc. */ /** * It contains all the classifiers in the population */ private Population pop; /** * It is a prediction array */ private PredictionArray predArray; /** * It is a reference to the train environment. */ private Environment env; /** * It is a reference to the test environment. */ private Environment testEnv; /** * It is an object to make statistics of the current run. */ private Statistic statistics; /** * <p> * It is a reference to the class that controls the time * run. * */ private TimeControl tControl = null; /** * <p> * Initializes an UCS object. * It configures the UCS run reading the configuration file. * </p> * @param configFile is the name of the config file. */ public UCS (String configFile){ System.out.println (" > Creating UCS object "); try{ System.out.println (" > Parsing the configuration file"); Config.doParse( configFile ); }catch(Exception e){ System.out.println ("Exception while parsing the configuration file"); System.exit(0); } if (Config.UCSRun.toLowerCase().equals("train")){ if (Config.typeOfProblem.toLowerCase().equals("mux")){ env = new MPEnvironment(); }else if (Config.typeOfProblem.toLowerCase().equals("fp")){ System.out.println (" > Loading the train set:"+Config.trainFile); env = new SSFileEnvironment(Config.trainFile, true); Config.r_0 = ((double)Config.clLength / (double)env.getNumberOfExamples()) * 100; System.out.println (" > R_0 has automatically been updated to: " + Config.r_0 ); } else { System.out.println ("There is any problem identified as '"+Config.typeOfProblem+"'"); } } else{ System.out.println ("Type of run not known: "+Config.UCSRun); System.exit(0); } if ( Config.doTest ){ if ( Config.typeOfProblem.toLowerCase().equals("mux") ){ testEnv = new MPEnvironment(); } else{ System.out.println ("\n > Loading the test set: "+Config.testFile); if (Config.UCSRun.equalsIgnoreCase("train")) testEnv = new SSFileEnvironment( Config.testFile, false ); else testEnv = new SSFileEnvironment( Config.testFile, true ); Config.numberOfTestExamples = testEnv.getNumberOfExamples(); } } if (Config.doStatistics){ System.out.println ("\n > Intializing the object for statistics."); statistics = new Statistic( ); } Config.setSeed((long) Config.seed); tControl = new TimeControl(); pop = null; } // end UCS /** * It runs the system. */ public void run (){ long iTime = System.currentTimeMillis(); startTrainUCS(); finishUCS(iTime); }//end run /** * Runs one UCS train experiment. It creates a new population and * calls the function doOneTrainExperiment. It makes explore and exploit * iterations. It also updates time statistics. */ public void startTrainUCS(){ int [] globalResults = createAndInitArray(3); // The initial time of the system is get to make statistics long iTrainTime = System.currentTimeMillis(); System.out.println ("\n\n================== STARTING THE TRAIN =================="); System.out.println("\n ------------ Some Output Statistics ------------"); System.out.println("Iteration - %Correct - Error - MicroCl - MacroCl"); // Does create a population of size Config.popSize + numberOfActions pop = new Population( Config.numberOfActions + Config.popSize ); // The function that makes one train experiment is called. doOneTrainExperiment( globalResults ); // Testing the data model with the train set doTestTrain( true ); // The time wasted in training is updated tControl.updateTrainTime( iTrainTime ); // Testing the data model with the test set doTest ( true ); // Printing the population pop.sortPopulation( 0, pop.getMacroClSum()-1, 0 ); statistics.printPopulation(pop); } //end startTrainUCS /** * Runs one train UCS experiment. Now, in the train run, one exploit is done between * N explores (where N is a parameter defined by the user). So, the operators of covering, * the GA and the update parameters routines are called in the explore runs. * * @param globalResults contains the addition of all classified, not classified * and correct and wrong classified examples of the exploit executions in the train. */ public void doOneTrainExperiment (int [] globalResults){ int tStamp=0,exploitNum=0; // Is the time of the UCS int [] windowExecutionResults = createAndInitArray(3); // We create a variable to store the error of the system in each exploit prediction. while ( tStamp < Config.numberOfExplores ){ double [] envState = env.newState(); int classOfExample = env.getCurrentClass(); // A single step explore iteration is made. doOneSingleStepExplore(envState, classOfExample, tStamp); // We look if a exploit has to be made. if (tStamp % Config.exploresBetweenExploits == 0 && tStamp != 0){ envState = env.newState(); classOfExample = env.getCurrentClass(); doOneSingleStepExploit( envState, classOfExample, tStamp, windowExecutionResults, false,0, false ); exploitNum++; // The screen statistics are made if it's necessary doScreenStatistics( tStamp, exploitNum, windowExecutionResults, globalResults ); } // The time of the system is updated. tStamp++; } // We write the last iteration results. doScreenStatistics(tStamp, exploitNum, windowExecutionResults, globalResults); // The last statistics are made. for ( int i=0; i<windowExecutionResults.length; i++ ){ globalResults[i] += windowExecutionResults[i]; windowExecutionResults[i] = 0; } // Enable if you want to sort the population with the classifiers numerosity pop.sortPopulation(0,pop.getMacroClSum() -1, 0); // The train statistics are printed //statistics.makeTrainStatistics(pop, Config.numberOfExplores, globalResults); } // end doOneTrainExperiment /** * <p> * Performs a test experiment. It does not apply the covering operator, the GA * and the update parameters routines. It only creates the match set and the * prediction array, choosing the best action. If there are more than * one action with the same probability, it chooses one of them randomly. * For the moment, the examples are chosen sequentially from the environment if it's * a file single step environment, to be sure that all the examples will participate * in the test run. * </p> * @param tEnv is the environment to do the test. It can be the same or different from * the train environment. * @param typeOfTest is a parameter that indicates the kind of test: testing with the test * set (0) or testing with the train set (1) * @param globalResults contains the addition of all classified, not classified and correct * and wrong classified examples of the exploit executions in the train. * </p> */ public void doOneTestExperiment( Environment tEnv, int typeOfTest, int [] globalResults, boolean writeExpOut ){ int tStamp=0; double [] envState = null; int [] windowExecutionResults = createAndInitArray(3); if (Config.sequentialTest) tEnv.beginSequentialExamples(); while ( tStamp<Config.numberOfTestExamples ){ // A new enviromental state is got. if ( Config.sequentialTest ) envState = tEnv.getSequentialState(); else envState = tEnv.newState(); int classOfExample = tEnv.getCurrentClass(); // An exploit is made with the new environmental state doOneSingleStepExploit( envState, classOfExample, tStamp, windowExecutionResults, true, typeOfTest, writeExpOut); // The statistics are written to file. Enable if you want partial results of test // doScreenStatistics(tStamp, tStamp, windowExecutionResults, globalResults); // The time of the system is incremented. tStamp++; } // We add the partial results to the global ones. for (int i=0; i<windowExecutionResults.length; i++){ globalResults[i] += windowExecutionResults[i]; windowExecutionResults[i] = 0; } // Screen statistics are made. doTestScreenStatistics( tStamp, globalResults, Config.numberOfTestExamples ); statistics.makeTestStatistics(pop, Config.numberOfTestExamples, globalResults, typeOfTest); } // end doOneTestExperiment /** * <p> * Performs one explore iteration. It applies the covering operator, the * GA and the update parameters routines if it is necessary. * </p> * @param envState is the new example that has to be classified. * @param tStamp is the current time stamp of the system. It is used to decide * if the GA has to be applied, and to create new classifiers. */ public void doOneSingleStepExplore( double [] envState, int classOfExample, int tStamp){ // Creating the match set Population matchSet = new Population( pop, envState ); // Creating the correct set Population correctSet = new Population( matchSet, envState, classOfExample, tStamp ); // Updating parameters of classifiers in [M] matchSet.updateParametersSet( correctSet.getMicroClSum(), envState, classOfExample, tStamp ); // At the end, we run the genetic algorithm. correctSet.runGA( tStamp, envState, classOfExample ); } // end doOneSingleStepExplore /** * <p> * Performs one single step exploit. It only chooses the best prediction * from the prediction array (it is not stochastic) * </p> * @param envState is the new example that has to be classified. * @param tStamp is the current time stamp of the system. It's used to * decide if the GA has to be applied, and to create new classifiers. * @param windowExecutionResults is an array where the results are set * down to make statistics. * @param typeOfTest indicates the test set kind (if is the test set (0) or the train * set (1) ) of the run. * @param writeExpOut determines is an output file with expected-real * output has to be writen. */ public void doOneSingleStepExploit( double [] envState, int classOfExample, int tStamp, int []windowExecutionResults, boolean isTest, int typeOfTest, boolean writeExpOut){ // We create the match set Population matchSet = new Population( pop, envState ); // With the match set the prediction array is created predArray = new PredictionArray( matchSet ); // We choose the best action in the prediction array, and get the reward of doing that. int action = predArray.getBestAction(); // We make the statistics if ( matchSet.getMacroClSum() > 0 && predArray.howManyBestActions() == 1){ statistics.printStateAndClass(envState,action); if ( action == classOfExample ) windowExecutionResults[0] ++; else windowExecutionResults[1] ++; } else{ // We guess for the majority class if ( Config.defaultRule ){ if ( Config.majorityClass == classOfExample ) windowExecutionResults[0] ++; else windowExecutionResults[1] ++; } else{ statistics.printStateAndClassNoCov(envState,-1); windowExecutionResults[2]++; } } // Writting the expected ouptut and the real output for a test instance if ( isTest && typeOfTest == 0 && writeExpOut ){ if ( matchSet.getMacroClSum() > 0 ) statistics.writeExpectedTestOut( classOfExample, action ); else statistics.writeExpectedTestOut( classOfExample, Config.majorityClass ); } // Writting the expected output and the real output for a train instance else if (isTest && typeOfTest == 1 && writeExpOut){ if ( matchSet.getMacroClSum() > 0 ) statistics.writeExpectedTrainOut( classOfExample, action ); else statistics.writeExpectedTrainOut( classOfExample, Config.majorityClass ); } } // end doOneSingleStepExploit /** * It makes a test between or at the end of the traininig * * @param writeExpOut indicates if the correct class and the predicted class have to * be printed for the test set according to the keel format */ private void doTest( boolean writeExpOut ){ long iTestTime = System.currentTimeMillis(); System.out.println ("\n============= MAKING TEST BETWEEN A TRAIN ============="); // A vector is initialited to make statistics int [] statisticsVector = createAndInitArray(3); doOneTestExperiment( testEnv, 0, statisticsVector, writeExpOut ); System.out.println ("=======================================================\n"); tControl.updateTestTime(iTestTime); } // end doTest /** * It makes a test with the train set. * * @param writeExpOut indicates if the correct class and the predicted class have to * be printed for the test set according to the keel format */ private void doTestTrain(boolean writeExpOut){ long iTestTime = System.currentTimeMillis(); System.out.println ("\n============= MAKING TEST WITH THE TRAIN SET ============="); // A vector is initialited to make statistics int [] statisticsVector = createAndInitArray(3); Config.numberOfTestExamples = env.getNumberOfExamples(); doOneTestExperiment( env, 1, statisticsVector, writeExpOut); Config.numberOfTestExamples = testEnv.getNumberOfExamples(); System.out.println ("=======================================================\n"); tControl.updateTestTime(iTestTime); }//end doTestTrain /** * <p> * It computes the statistics * </p> * @param tStamp is the time of the UCS. * @param exploitNum is the number of exploits that UCS has made. * @param statisticVector is the vector that contains all the statistics * @param globalResults is a vector with the global results statistics. */ public void doScreenStatistics (int tStamp, int exploitNum, int [] statisticVector, int [] globalResults){ if (exploitNum %Config.statisticWindowSize == 0 && exploitNum != 0){ System.out.print (tStamp+" "+((double)statisticVector[0]/ ((double)Config.statisticWindowSize)) ); System.out.println (" "+pop.getMacroClSum()+" "+pop.getMicroClSum()); statistics.makeIncStatistics( pop, tStamp, statisticVector ); for (int i=0; i<statisticVector.length; i++){ globalResults[i] += statisticVector[i]; statisticVector[i] = 0; } } }//doScreenStatistics /** * <p> * It does test screen statistics * </p> * @param tStamp is the system time. * @param globalResults is the sum of all statistics done in the system. * @param numProblems is the number of examples done in the run. */ public void doTestScreenStatistics(int tStamp, int []globalResults, int numProblems){ System.out.println ("\nGlobal results of test execution: "); System.out.println ("Correct: "+globalResults[0]+" Incorrect: "+globalResults[1]+" not Covered: "+globalResults[2]); System.out.println (tStamp+" "+((double)globalResults[0]/(double)numProblems)+" "+" "+pop.getMacroClSum()+" "+pop.getMicroClSum()+" "); }//end doTestScreenStatistics /** * Creates and initializes an integer vector of size N * @param N is the size of the vector that has to be created */ public int [] createAndInitArray(int N){ int [] vect = new int[N]; for (int i=0; i<N; i++) vect[i] = 0; return vect; }//end createAndInitArray /** * <p> * It makes the last things to do after closing the program. It upgrades the times, print the last * statistics and close all opened files. * </p> * @param iTime is the actual time. */ public void finishUCS(long iTime) { tControl.updateTotalTime (System.currentTimeMillis() - iTime); tControl.printTimes(); if (statistics != null){ statistics.makeTimeStatistics(tControl); statistics.closeFiles(); } } // end finishUCS /** * Does print the population and stops the execution. * @param r is the bufferedReader where to read. */ public void print ( BufferedReader r ) { try{ pop.print(); System.out.println ("Print something to return to the menu"); r.readLine(); }catch (Exception e){ e.printStackTrace(); } } //end print } // end UCS