/*********************************************************************** 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 * @author Modified by Jose A. Saez Munoz (ETSIIT, Universidad de Granada - Granada) 10/09/10 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.MPLCS; import java.util.Vector; import keel.Dataset.*; import keel.Algorithms.Genetic_Rule_Learning.MPLCS.Assistant.Globals.*; public class ClassifierADI extends Classifier implements Cloneable { /** * <p> * Contains the classifier for the ADI knowledge representation * </p> */ // The cromosome int[] crm; int length; int defaultClass; public ClassifierADI() { isEvaluated = false; } public void initRandomClassifier() { numRules = Parameters.initialNumberOfRules; int ruleSize = Globals_ADI.ruleSize; crm = new int[numRules * ruleSize]; int base = 0; length = 0; if (Globals_DefaultC.defaultClassPolicy == Globals_DefaultC.AUTO) { defaultClass = Rand.getInteger(0, Parameters.numClasses - 1); } else { defaultClass = Globals_DefaultC.defaultClass; } for (int i = 0; i < numRules; i++) { AdaptiveRule.constructor(crm, base, defaultClass); length += crm[base]; base += ruleSize; } resetPerformance(); } public double computeTheoryLength() { int base = 0; int ruleSize = Globals_ADI.ruleSize; theoryLength = 0; for (int i = 0; i < numRules; i++) { if (PerformanceAgent.getActivationsOfRule(i) > 0) { theoryLength += AdaptiveRule.computeTheoryLength(crm, base); } base += ruleSize; } if (Globals_DefaultC.enabled) { theoryLength += 0.00000001; } return theoryLength; } public double getLength() { return length * (double) numAliveRules / (double) numRules; } /** * This function classifies input instances. It returns a class * prediction of -1 if the input example cannot be classified */ public int doMatch(InstanceWrapper ins) { int i; int base = 0; int ruleSize = Globals_ADI.ruleSize; for (i = 0; i < numRules; i++) { if (AdaptiveRule.doMatch(crm, base, ins)) { positionRuleMatch = i; return crm[base + 1]; } base += ruleSize; } if (Globals_DefaultC.enabled) { positionRuleMatch = numRules; return defaultClass; } return -1; } public void printClassifier() { int ruleSize = Globals_ADI.ruleSize; String str; int base = 0; for (int i = 0; i < numRules; i++) { str = i + ":"; str += AdaptiveRule.dumpPhenotype(crm, base); LogManager.println(str); base += ruleSize; } if (Globals_DefaultC.enabled) { LogManager.println(numRules + ":Default rule -> " + Attributes.getAttribute(Parameters.numAttributes). getNominalValue(defaultClass)); } } public int getNumRules() { if (Globals_DefaultC.enabled) { return numRules + 1; } return numRules; } public Classifier[] crossoverClassifiers(Classifier _parent2) { ClassifierADI offspring1 = new ClassifierADI(); ClassifierADI offspring2 = new ClassifierADI(); ClassifierADI parent2 = (ClassifierADI) _parent2; int ruleSize = Globals_ADI.ruleSize; int ruleP1 = (int) Rand.getInteger(0, numRules - 1); int ruleP2 = (int) Rand.getInteger(0, parent2.numRules - 1); offspring1.numRules = ruleP1 + parent2.numRules - ruleP2; offspring2.numRules = ruleP2 + numRules - ruleP1; int cutPoint = Rand.getInteger(0, Parameters.numAttributes); offspring1.defaultClass = offspring2.defaultClass = defaultClass; offspring1.crm = new int[ruleSize * offspring1.numRules]; offspring2.crm = new int[ruleSize * offspring2.numRules]; System.arraycopy(crm, 0, offspring1.crm, 0, ruleP1 * ruleSize); System.arraycopy(parent2.crm, 0, offspring2.crm, 0, ruleP2 * ruleSize); AdaptiveRule.crossover(crm, parent2.crm, offspring1.crm , offspring2.crm, ruleP1 * ruleSize, ruleP2 * ruleSize , cutPoint); int base1 = (ruleP1 + 1) * ruleSize; int base2 = (ruleP2 + 1) * ruleSize; System.arraycopy(crm, base1, offspring2.crm, base2, (numRules - ruleP1 - 1) * ruleSize); System.arraycopy(parent2.crm, base2, offspring1.crm, base1, (parent2.numRules - ruleP2 - 1) * ruleSize); int base = 0; offspring1.length = 0; for (int i = 0; i < offspring1.numRules; i++) { offspring1.length += offspring1.crm[base]; base += ruleSize; } base = 0; offspring2.length = 0; for (int i = 0; i < offspring2.numRules; i++) { offspring2.length += offspring2.crm[base]; base += ruleSize; } Classifier[] ret = new Classifier[2]; ret[0] = offspring1; ret[1] = offspring2; return ret; } public Classifier copy() { int ruleSize = Globals_ADI.ruleSize; ClassifierADI ret = new ClassifierADI(); ret.numRules = numRules; ret.theoryLength = theoryLength; ret.exceptionsLength = ret.exceptionsLength; ret.length = length; ret.accuracy = accuracy; ret.fitness = fitness; ret.isEvaluated = isEvaluated; ret.numAliveRules = numAliveRules; ret.defaultClass = defaultClass; ret.crm = new int[numRules * ruleSize]; System.arraycopy(crm, 0, ret.crm, 0, numRules * ruleSize); return ret; } public void doMutation() { int whichRule = Rand.getInteger(0, numRules - 1); int ruleSize = Globals_ADI.ruleSize; int base = whichRule * ruleSize; AdaptiveRule.mutation(crm, base, defaultClass); isEvaluated = false; } public void deleteRules(int[] whichRules) { if (numRules == 1 || whichRules.length == 0) { return; } int ruleSize = Globals_ADI.ruleSize; int rulesToDelete = whichRules.length; if (whichRules[rulesToDelete - 1] == numRules) { rulesToDelete--; } int[] newCrm = new int[ruleSize * (numRules - rulesToDelete)]; int countPruned = 0; int baseOrig = 0; int baseNew = 0; for (int i = 0; i < numRules; i++) { if (countPruned < rulesToDelete) { if (i != whichRules[countPruned]) { System.arraycopy(crm, baseOrig, newCrm, baseNew, ruleSize); baseNew += ruleSize; } else { countPruned++; } } else { System.arraycopy(crm, baseOrig, newCrm, baseNew, ruleSize); baseNew += ruleSize; } baseOrig += ruleSize; } numRules -= rulesToDelete; crm = newCrm; } public int numSpecialStages() { return 3; } public void doSpecialStage(int stage) { if (stage == 0) { doSplit(); } else if (stage == 1) { doMerge(); } else if (stage == 2) { doReinitialize(); } else { LogManager.printErr("Unknown special stage !!"); System.exit(1); } } public void doSplit() { int base = 0; for (int i = 0; i < numRules; i++) { length -= crm[base]; if (AdaptiveRule.doSplit(crm, base)) { isEvaluated = false; } length += crm[base]; base += Globals_ADI.ruleSize; } } public void doMerge() { int base = 0; for (int i = 0; i < numRules; i++) { length -= crm[base]; if (AdaptiveRule.doMerge(crm, base)) { isEvaluated = false; } length += crm[base]; base += Globals_ADI.ruleSize; } } public void doReinitialize() { int base = 0; for (int i = 0; i < numRules; i++) { length -= crm[base]; if (AdaptiveRule.doReinitialize(crm, base)) { isEvaluated = false; } length += crm[base]; base += Globals_ADI.ruleSize; } } public int getNiche() { if (Globals_DefaultC.defaultClassPolicy != Globals_DefaultC.AUTO) { return 0; } return defaultClass; } public int getNumNiches() { if (Globals_DefaultC.defaultClassPolicy != Globals_DefaultC.AUTO) { return 1; } return Parameters.numClasses; } public void doLocalSearch(){ } public void crossoverRSW(Classifier[] parents, int num){ int i, k; int ruleSize=Globals_ADI.ruleSize; Vector<int[]> candidateRules = new Vector<int[]>(50,10); Vector<matchProfileAgent>profiles = new Vector<matchProfileAgent>(50,10); int ruleCount=0; for(k=0;k<num;k++) { ClassifierADI parent=(ClassifierADI)parents[k]; int pos=0; for(i=0;i<parent.numRules;pos+=Globals_ADI.ruleSize,i++) { int[] newRule = new int[ruleSize]; System.arraycopy(parent.crm, pos, newRule, 0, ruleSize); matchProfileAgent mpa = evaluateRuleCX(newRule); candidateRules.addElement(newRule); ruleCount++; profiles.addElement(mpa); } } Vector<Integer> ruleOrder = new Vector<Integer>(50,10); findOrder(profiles,candidateRules,ruleOrder); numRules = ruleOrder.size(); int length2 = numRules * ruleSize; crm = new int[length2]; length = 0; for (i = 0; i < numRules; i++){ System.arraycopy(candidateRules.get(ruleOrder.get(i)), 0, crm,i*ruleSize , ruleSize); length += candidateRules.get(ruleOrder.get(i))[0]; } } public matchProfileAgent evaluateRuleCX(int[] rule){ int i; int cl = rule[1]; int max = PopulationWrapper.ilas.getNumInstancesOfIteration(); InstanceWrapper[] instances = PopulationWrapper.ilas.getInstances(); matchProfileAgent mpa=new matchProfileAgent(max,cl); for (i = 0; i < max; i++) { if (AdaptiveRule.doMatch(rule,0, instances[i])) { if (instances[i].instanceClass == cl) { mpa.addOK(i); } else { mpa.addKO(i); } } } mpa.generateProfiles(); return mpa; } public void findOrder(Vector<matchProfileAgent> profiles, Vector<int[]>candidateRules,Vector<Integer> ruleOrder){ int numInst=PopulationWrapper.ilas.getNumInstancesOfIteration(); int i,j; int totalRules=profiles.size(); ruleOrderAgent best=null; for(j=0;j<Parameters.repetitionsRuleOrdering;j++) { Sampling samp=new Sampling(totalRules); ruleOrderAgent roa = new ruleOrderAgent(defaultClass,numInst,totalRules); for(i=0;i<totalRules;i++) { int rule=samp.getSample(); roa.insertRule(rule,profiles.get(rule)); } roa.refineRuleSet(); if(best==null) { best=roa; } else { double accOld=best.getAccuracy(); double accNew=roa.getAccuracy(); if(accNew>accOld) { best=roa; } else if(accNew==accOld && roa.getNumRules()<best.getNumRules()) { best=roa; } else { } } } best.copyOrder(ruleOrder); if(ruleOrder.size()==0) { int pos=Rand.getInteger(0, totalRules-1); ruleOrder.addElement(pos); } } }