/*********************************************************************** 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 Jaume Bacardit (La Salle, Ram�n Llull University - Barcelona) 28/03/2004 * @author Modified by Xavi Sol� (La Salle, Ram�n Llull University - Barcelona) 23/12/2008 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.MPLCS; import keel.Dataset.*; import keel.Algorithms.Genetic_Rule_Learning.MPLCS.Assistant.Globals.*; public class PopulationWrapper { /** * <p> * Contains methods that manipulate the population in various * ways: classifying the training set for the fitness computations, checking * if there are improved solutions in the population and performing the * test stage (generating the output files) * </p> */ static public InstanceSet is; static public Windowing ilas; static public InstanceWrapper[] allInstances; static public int[][] instancesByClass; static public Sampling[] samplesOfClasses; static public boolean smartInit; static public boolean cwInit; public static int getCurrentVersion() { return ilas.getCurrentVersion(); } public static int numVersions() { return ilas.numVersions(); } public static void initInstancesEvaluation() { is = new InstanceSet(); try { is.readSet(Parameters.trainInputFile, true); } catch (Exception e) { LogManager.printErr(e.toString()); System.exit(1); } checkDataset(); replaceMissing(is); if (Parameters.adiKR) { DiscretizationManager.init(); } allInstances = createWrapperInstances(is); ilas = new Windowing(allInstances); if (Parameters.initMethod != null) { if (Parameters.initMethod.equalsIgnoreCase("smart")) { smartInit = true; cwInit = false; } else if (Parameters.initMethod.equalsIgnoreCase("cwInit")) { smartInit = true; cwInit = true; } else { smartInit = false; cwInit = false; } } else { smartInit = false; cwInit = false; } if (smartInit) { int nc = Parameters.numClasses; int classCounts[] = new int[nc]; instancesByClass = new int[nc][]; samplesOfClasses = new Sampling[nc]; for (int i = 0; i < nc; i++) { int num = numInstancesOfClass(i); instancesByClass[i] = new int[num]; samplesOfClasses[i] = new Sampling(num); classCounts[i] = 0; } for (int i = 0; i < allInstances.length; i++) { int cl = allInstances[i].classOfInstance(); instancesByClass[cl][classCounts[cl]++] = i; } } } public static InstanceWrapper getInstanceInit(int forbiddenCL) { if (cwInit) { int cl; do { cl = Rand.getInteger(0, Parameters.numClasses - 1); } while (cl == forbiddenCL || instancesByClass[cl].length == 0); int pos = samplesOfClasses[cl].getSample(); return allInstances[instancesByClass[cl][pos]]; } int count[] = new int[Parameters.numClasses]; int total = 0; for (int i = 0; i < count.length; i++) { if (i == forbiddenCL) { count[i] = 0; } else { count[i] = samplesOfClasses[i].numSamplesLeft(); total += count[i]; } } int pos = Rand.getInteger(0, total - 1); int acum = 0; for (int i = 0; i < count.length; i++) { acum += count[i]; if (pos < acum) { int inst = samplesOfClasses[i].getSample(); return allInstances[instancesByClass[i][inst]]; } } LogManager.printErr("We should not be here !!!"); System.exit(1); return null; } public static InstanceWrapper[] createWrapperInstances(InstanceSet is) { InstanceWrapper[] iw = new InstanceWrapper[is.getNumInstances()]; for (int i = 0; i < iw.length; i++) { iw[i] = new InstanceWrapper(is.getInstance(i)); } return iw; } public static boolean initIteration() { return ilas.newIteration(); } public static void evaluateClassifier(Classifier ind) { int predicted, real; InstanceWrapper[] instances = ilas.getInstances(); ind.resetPerformance(); PerformanceAgent.resetPerformance(ind.getNumRules()); for (int i = 0; i < instances.length; i++) { real = instances[i].classOfInstance(); predicted = ind.doMatch(instances[i]); PerformanceAgent.addPrediction(predicted, real , ind.getPositionRuleMatch()); } ind.computePerformance(); if (Parameters.doRuleDeletion) { ind.deleteRules(PerformanceAgent.controlBloatRuleDeletion()); } } public static void doEvaluation(Classifier[] _population) { Chronometer.startChronEvaluation(); int popSize = _population.length; for (int i = 0; i < popSize; i++) { if (!_population[i].getIsEvaluated()) { evaluateClassifier(_population[i]); } } Chronometer.stopChronEvaluation(); } /** * Obtains the best classifier of population. * @param _population The population * @return Best classifier of population. */ public static Classifier getBest(Classifier[] _population) { int sizePop = _population.length; int posWinner = 0; for (int i = 1; i < sizePop; i++) { if (_population[i].compareToIndividual(_population[posWinner])) { posWinner = i; } } return _population[posWinner]; } /** * Obtains the worst classifier of population. * @param _population The population * @return Worst classifier of population. */ public static int getWorst(Classifier[] _population) { int sizePop = _population.length; int posWorst = 0; for (int i = 1; i < sizePop; i++) { if (!_population[i].compareToIndividual(_population[posWorst])) { posWorst = i; } } return posWorst; } public static void setModified(Classifier[] _population) { int sizePop = _population.length; for (int i = 0; i < sizePop; i++) { _population[i].setIsEvaluated(false); } } public static void testClassifier(Classifier ind, String typeOfTest, String testInputFile, String testOutputFile) { InstanceSet testSet = new InstanceSet(); try { testSet.readSet(testInputFile,false); } catch(Exception e) { LogManager.printErr(e.toString()); System.exit(1); } replaceMissing(testSet); FileManagement fm = new FileManagement(); InstanceWrapper []instances=createWrapperInstances(testSet); double numInstances=instances.length; int real, predicted; PerformanceAgent.resetPerformanceTest(ind.getNumRules()); ind.resetPerformance(); //Attribute att = Attributes.getAttribute(Parameters.numAttributes); Attribute att = Attributes.getOutputAttribute(0); try { fm.initWrite(testOutputFile); fm.writeLine(testSet.getHeader()); for(int i=0;i<numInstances;i++) { real=instances[i].classOfInstance(); predicted=ind.doMatch(instances[i]); String pred; if(predicted==-1) { pred="unclassified"; } else { pred=att.getNominalValue(predicted); } fm.writeLine(att.getNominalValue(real)+" "+pred+"\n"); PerformanceAgent.addPredictionTest(predicted,real ,ind.getPositionRuleMatch()); } fm.closeWrite(); } catch(Exception e) { System.err.println("Error handling output test file "+testOutputFile); System.exit(1); } LogManager.println("\nStatistics on "+typeOfTest+" file"); PerformanceAgent.dumpStats(typeOfTest); LogManager.println(""); } static void checkDataset() { Attribute[] outputs = Attributes.getOutputAttributes(); if (outputs.length != 1) { LogManager.printErr("Only datasets with one output are supported"); System.exit(1); } if (outputs[0].getType() != Attribute.NOMINAL) { LogManager.printErr("Output attribute should be nominal"); System.exit(1); } Parameters.numClasses = outputs[0].getNumNominalValues(); Parameters.numAttributes = Attributes.getInputAttributes().length; } static void replaceMissing(InstanceSet is) { String[][] mostFreq = new String[Parameters.numAttributes][Parameters. numClasses]; double[][] means = new double[Parameters.numAttributes][Parameters. numClasses]; int[] types = new int[Parameters.numAttributes]; Attribute[] inputs = Attributes.getInputAttributes(); for (int i = 0; i < Parameters.numAttributes; i++) { types[i] = inputs[i].getType(); if (types[i] == Attribute.NOMINAL) { for (int j = 0; j < Parameters.numClasses; j++) { mostFreq[i][j] = inputs[i].getMostFrequentValue(j); } } else { for (int j = 0; j < Parameters.numClasses; j++) { means[i][j] = inputs[i].getMeanValue(j); } } } Instance[] inst = is.getInstances(); for (int i = 0; i < inst.length; i++) { if (inst[i].existsAnyMissingValue()) { int cl = inst[i].getOutputNominalValuesInt(0); boolean[] miss = inst[i].getInputMissingValues(); for (int j = 0; j < Parameters.numAttributes; j++) { if (miss[j]) { if (types[j] == Attribute.NOMINAL) { inst[i].setInputNominalValue(j, mostFreq[j][cl]); } else { inst[i].setInputNumericValue(j, means[j][cl]); } } } } } } static int numInstancesOfClass(int clas){ int count = 0; Instance [] inst = is.getInstances(); for (int i = 0; i < inst.length; i++){ if (inst[i].getOutputNominalValuesInt(0) == clas){ count++; } } return count; } }