/***********************************************************************
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.GAssist;
import keel.Dataset.*;
import keel.Algorithms.Genetic_Rule_Learning.Globals.*;
public class ClassifierGABIL
extends Classifier implements Cloneable {
/**
* <p>
* Contains the classifier for the GABIL knowledge representation
* </p>
*/
// The cromosome
int[] crm;
int defaultClass;
public ClassifierGABIL() {
isEvaluated = false;
}
public void initRandomClassifier() {
numRules = Parameters.initialNumberOfRules;
int ruleSize = Globals_GABIL.ruleSize;
double prob = Parameters.probOne;
int nC = Parameters.numClasses;
crm = new int[numRules * ruleSize];
int base = 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++) {
InstanceWrapper ins = null;
if (PopulationWrapper.smartInit) {
if (Globals_DefaultC.defaultClassPolicy != Globals_DefaultC.DISABLED) {
ins = PopulationWrapper.getInstanceInit(defaultClass);
}
else {
ins = PopulationWrapper.getInstanceInit(Parameters.numClasses);
}
}
int base2 = base;
for (int j = 0; j < Parameters.numAttributes; j++) {
int value;
if (ins != null) {
value = ins.getNominalValue(j);
}
else {
value = -1;
}
for (int k = 0; k < Globals_GABIL.size[j]; k++) {
if (k != value) {
if (Rand.getReal() < prob) {
crm[base2 + k] = 1;
}
else {
crm[base2 + k] = 0;
}
}
else {
crm[base2 + k] = 1;
}
}
base2 += Globals_GABIL.size[j];
}
if (ins != null) {
crm[base2] = ins.classOfInstance();
}
else {
do {
crm[base2] = Rand.getInteger(0, nC - 1);
}
while (Globals_DefaultC.enabled &&
crm[base2] == defaultClass);
}
base += ruleSize;
}
resetPerformance();
}
public double computeTheoryLength() {
int base = 0;
int ruleSize = Globals_GABIL.ruleSize;
theoryLength = 0;
for (int i = 0; i < numRules; i++) {
if (PerformanceAgent.getActivationsOfRule(i) > 0) {
int base2 = base;
for (int j = 0; j < Parameters.numAttributes; j++) {
double countFalses = 0;
int numValues = Globals_GABIL.size[j];
for (int k = 0; k < numValues; k++) {
if (crm[base2 + k] == 0) {
countFalses++;
}
}
theoryLength += numValues + countFalses;
base2 += Globals_GABIL.size[j];
}
}
base += ruleSize;
}
if (Globals_DefaultC.enabled) {
theoryLength += 0.00000001;
}
return theoryLength;
}
/**
* 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 nA = Parameters.numAttributes;
boolean okMatch;
int i, j;
int base = 0;
int ruleSize = Globals_GABIL.ruleSize;
int[] val = ins.getNominalValues();
for (i = 0; i < numRules; i++) {
okMatch = true;
for (j = 0; okMatch && j < nA; j++) {
if (crm[base + Globals_GABIL.offset[j] + val[j]] == 0) {
okMatch = false;
}
}
if (okMatch) {
positionRuleMatch = i;
return crm[base + ruleSize - 1];
}
base += ruleSize;
}
if (Globals_DefaultC.enabled) {
positionRuleMatch = numRules;
return defaultClass;
}
return -1;
}
public void printClassifier() {
int nA = Parameters.numAttributes;
int ruleSize = Globals_GABIL.ruleSize;
String str;
int base = 0;
for (int i = 0; i < numRules; i++) {
str = i + ":";
for (int j = 0; j < nA; j++) {
Attribute att = Attributes.getAttribute(j);
String temp = "Att " + att.getName() + " is ";
boolean irr = true;
boolean first = true;
for (int k = 0; k < Globals_GABIL.size[j]; k++) {
if (crm[base + Globals_GABIL.offset[j] + k] == 1) {
if (first) {
temp += att.getNominalValue(k);
first = false;
}
else {
temp += "," + att.getNominalValue(k);
}
}
else {
irr = false;
}
}
if (!irr) {
str += temp + "|";
}
}
int cl = crm[base + ruleSize - 1];
String name = Attributes.getAttribute(Parameters.numAttributes).
getNominalValue(cl);
str += name;
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) {
ClassifierGABIL offspring1 = new ClassifierGABIL();
ClassifierGABIL offspring2 = new ClassifierGABIL();
ClassifierGABIL parent2 = (ClassifierGABIL) _parent2;
int ruleSize = Globals_GABIL.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 = (int) Rand.getInteger(0, Globals_GABIL.ruleSize);
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);
int base1 = ruleP1 * ruleSize;
int base2 = ruleP2 * ruleSize;
System.arraycopy(crm, base1, offspring1.crm, base1, cutPoint);
System.arraycopy(parent2.crm, base2, offspring2.crm, base2, cutPoint);
System.arraycopy(crm, base1 + cutPoint, offspring2.crm, base2 + cutPoint,
ruleSize - cutPoint);
System.arraycopy(parent2.crm, base2 + cutPoint, offspring1.crm,
base1 + cutPoint, ruleSize - cutPoint);
base1 += ruleSize;
base2 += 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);
Classifier[] ret = new Classifier[2];
ret[0] = offspring1;
ret[1] = offspring2;
return ret;
}
public Classifier copy() {
int ruleSize = Globals_GABIL.ruleSize;
ClassifierGABIL ret = new ClassifierGABIL();
ret.numRules = numRules;
ret.theoryLength = theoryLength;
ret.exceptionsLength = ret.exceptionsLength;
ret.crm = new int[numRules * ruleSize];
System.arraycopy(crm, 0, ret.crm, 0, numRules * ruleSize);
ret.defaultClass = defaultClass;
ret.setAccuracy(accuracy);
ret.setFitness(fitness);
ret.isEvaluated = isEvaluated;
ret.setNumAliveRules(numAliveRules);
return ret;
}
public void doMutation() {
int whichRule = (int) Rand.getInteger(0, numRules - 1);
int ruleSize = Globals_GABIL.ruleSize;
int base = whichRule * ruleSize;
int gene;
if (Globals_DefaultC.numClasses > 1
&& Rand.getReal() < 0.1) {
gene = ruleSize - 1;
}
else {
gene = (int) Rand.getInteger(0, ruleSize - 2);
}
if (gene < ruleSize - 1) {
if (crm[base + gene] == 1) {
crm[base + gene] = 0;
}
else {
crm[base + gene] = 1;
}
}
else {
int oldValue = crm[base + gene];
int newValue;
do {
newValue = (int) Rand.getInteger(0, Parameters.numClasses - 1);
}
while (newValue == oldValue ||
(Globals_DefaultC.enabled && newValue == defaultClass));
crm[base + gene] = newValue;
}
isEvaluated = false;
}
public void deleteRules(int[] whichRules) {
if (numRules == 1 || whichRules.length == 0) {
return;
}
int ruleSize = Globals_GABIL.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 double getLength() {
return numAliveRules;
}
public int numSpecialStages() {
return 0;
}
public void doSpecialStage(int stage) {}
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;
}
}