/***********************************************************************
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);
}
}
}