/***********************************************************************
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 Writed by Pedro Gonz�lez (University of Jaen) 15/02/2004
* @author Modified by Pedro Gonz�lez (University of Jaen) 4/08/2007
* @author Modified by Crist�bal J. Carmona (University of Jaen) 30/04/2010
* @version 2.0
* @since JDK1.5
* </p>
*/
package keel.Algorithms.Subgroup_Discovery.MESDIF.MESDIF;
import keel.Algorithms.Subgroup_Discovery.MESDIF.Calculate.*;
import org.core.*;
public class IndDNF extends Individual{
/**
* <p>
* Defines an individual composed by a DNF cromosome.
* </p>
*/
public CromDNF cromosoma; // Individual contents
/**
* <p>
* Creates new instance of IndDNF
* </p>
* @param AG Instance of the genetic algorithm
* @param length Length of the individual
* @param Variables Structure of the variables
* @param numExamples Number of examples of the data set
* @param numObjectives Number of objectives of the algorithm
*/
public IndDNF(Genetic AG, int length, TableVar Variables, int numExamples, int numObjectives) {
tamano = length;
cromosoma = new CromDNF(length, Variables);
medidas = new QualityMeasures(AG, numObjectives);
evaluado = false;
cubre = new boolean [numExamples];
}
/**
* <p>
* Returns if the indicated individual is equal to "this"
* <p>
* Used to know if two individuals describe the same rule
*
* @param otro Individual to compare with this
* @return true if the individuals are equal
*/
public boolean equalTo (Individual otro) {
boolean equals= true;
int number;
for (int i=0;i<this.tamano;i++) {
number = this.getIndivCromDNF().getCromGeneLength(i);
for (int j=0;j<number;j++) {
if (this.getCromElemGene(i,j) != otro.getCromElemGene(i,j)) {
equals = false;
break;
}
}
}
return equals;
}
/**
* <p>
* Creates random instance of DNF individual
* </p>
* @param Variables Variables structure
*/
public void InitIndRnd(TableVar Variables) {
cromosoma.initCromRnd(); // Random initialization method
evaluado = false; // Individual not evaluated
}
/**
* <p>
* Creates biased random instance of Canonical individual
* </p>
* @param Variables Variables structure
*/
public void InitIndBsd(TableVar Variables, float porcVar) {
cromosoma.initCromBsd(porcVar); // Biased random initialization method
evaluado = false; // Individual not evaluated
}
/**
* <p>
* Copy the indicaded individual in "this" individual
* <p>
* @param otro Individual to be copied
*/
public void copyIndiv (Individual otro) {
int number;
for (int i=0;i<this.tamano;i++) {
number = otro.getIndivCromDNF().getCromGeneLength(i);
for (int j=0;j<=number;j++) {
// <= is used to copy also the bit indicating that the gene takes part in the rule
this.setCromElemGene(i,j, otro.getCromElemGene(i, j));
}
}
this.setIndivFitness(otro.getIndivFitness());
this.setIndivEvaluated(otro.getIndivEvaluated());
this.setIndivDom(otro.getIndivDom());
this.medidas.copy (otro.medidas);
for (int i=0;i<cubre.length;i++)
this.cubre[i] = otro.cubre[i];
}
/**
* <p>
* Returns the Chromosome
* </p>
* @return Chromosome
*/
public CromDNF getIndivCromDNF () {
return cromosoma;
}
/**
* <p>
* Returns the Chromosome
* </p>
* @return Chromosome
*/
public CromCAN getIndivCromCAN () {
return null;
}
/**
* <p>
* Returns the indicated gene of the Chromosome
* </p>
* @param pos Position of the gene
* @return Value of the gene
*/
public int getCromElem (int pos) {
return 0;
}
/**
* <p>
* Returns the value of the indicated gene for the variable
* </p>
* @param pos Position of the variable
* @param elem Position of the gene
* @return Value of the gene
*/
public int getCromElemGene (int pos, int elem) {
return cromosoma.getCromElemGene (pos, elem);
}
/**
* <p>
* Sets the value of the indicated gene of the Chromosome
* </p>
* @param pos Position of the variable
* @param val Value of the variable
*/
public void setCromElem (int pos, int val) {
}
/**
* <p>
* Sets the value of the indicated gene of the Chromosome
* </p>
* @param pos Position of the variable
* @param elem Position of the gene
* @param val Value of the variable
*/
public void setCromElemGene (int pos, int elem, int val) {
cromosoma.setCromElemGene(pos, elem, val);
}
/**
* <p>
* Evaluate a individual. This function evaluates an individual.
* </p>
* @param AG Genetic algorithm
* @param Variables Variables structure
* @param Examples Ejemplos structure
*/
public void evalInd (Genetic AG, TableVar Variables, TableDat Examples) {
int ejCompAntFuzzy=0; // Number of compatible examples with the antecedent of any class - fuzzy version
int ejCompAntCrisp=0; // Number of compatible examples with the antecedent of any class - crisp version
int ejCompAntClassFuzzy=0; // Number of compatible examples (antecedent and class) - fuzzy version
int ejCompAntClassCrisp=0; // Number of compatible examples (antecedent and class) - crisp version
float gradoCompAntFuzzy=0; // Total compatibility degree with the antecedent - fuzzy version
float gradoCompAntClassFuzzy=0; // Tot compatibility degree with antecedent and class - fuzzy version
float disparoFuzzy; // Final compatibility degree of the example with the individual - fuzzy version
float disparoCrisp; // Final compatibility or not of the example with the individual - crisp version
float csupport, fsupport, support, confianza, cconfianza;
float coverage, unusualness, accuracy, significance;
// For the significance computation we need the number of examples and the number of examples covered of each class
int ejClase[] = new int[Variables.getNClass()];
int cubreClase[] = new int[Variables.getNClass()];
for (int i=0; i<Variables.getNClass(); i++) {
cubreClase[i]=0;
ejClase[i] = Examples.getExamplesClass (i);
}
/* Variable initialization */
int numVarNoInterv=0; // Number of variables not taking part in the individual
for (int i=0; i<Examples.getNEx(); i++) { // For each example of the dataset
// Initialization
disparoFuzzy = 1;
disparoCrisp = 1;
numVarNoInterv = 0;
// Compute all chromosome values
for (int j=0; j<Variables.getNVars(); j++) {
if (!Variables.getContinuous(j)) {
// Discrete Variable
if (cromosoma.getCromElemGene(j,Variables.getNLabelVar(j))==1){
// Variable j takes part in the rule
if ((cromosoma.getCromElemGene(j,(int)Examples.getDat(i,j))==0) && (!Examples.getLost(Variables,i,j))) {
disparoFuzzy = 0; // not compatible
disparoCrisp = 0; // not compatible
}
}
else
numVarNoInterv++; // Variable does not take part
}
else {
// Continuous variable
if (cromosoma.getCromElemGene(j,Variables.getNLabelVar(j))==1){
// Variable takes part in the rule
// Fuzzy computation
if (!Examples.getLost(Variables,i,j)) {
float pertenencia = 0;
float pert;
for (int k=0; k<Variables.getNLabelVar(j); k++) {
if (cromosoma.getCromElemGene(j,k)==1)
pert = Variables.Fuzzy (j, k, Examples.getDat(i,j));
else pert = 0;
pertenencia = Utils.Maximum (pertenencia, pert);
}
disparoFuzzy = Utils.Minimum (disparoFuzzy, pertenencia);
}
// Crisp computation
if (!Examples.getLost(Variables,i,j))
if (cromosoma.getCromElemGene(j,NumInterv(Examples.getDat(i,j),j, Variables))==0)
disparoCrisp = 0;
}
else
numVarNoInterv++; // Variable does not take part
}
} // End FOR all chromosome values
// Update counters and mark example if needed
gradoCompAntFuzzy += disparoFuzzy;
if (disparoFuzzy>0) {
ejCompAntFuzzy++;
if (Examples.getClass(i) == Variables.getNumClassObj()) {
gradoCompAntClassFuzzy +=disparoFuzzy;
ejCompAntClassFuzzy ++;
cubre[i]=true;
}
}
if (disparoCrisp>0) {
ejCompAntCrisp++;
if (Examples.getClass(i) == Variables.getNumClassObj()) {
ejCompAntClassCrisp ++;
cubre[i]=true;
}
// (Sign computation)
// Increases #examples of the class of the example covered by the rule
// with independence of the class of the rule
cubreClase[Examples.getClass(i)]++;
}
} // End of cycle for each example
// Compute the measures
// Support (Lavrac) - (Crisp): Number of examples compatibles with antecedent and class / total number of exammples
support = ((float)ejCompAntClassCrisp/Examples.getNEx());
// FSupport - (Fuzzy): degree of compatibility with antecedent and class / total examples
if (Examples.getNEx() != 0)
fsupport = ((float)gradoCompAntClassFuzzy/Examples.getNEx());
else
fsupport = 0;
// CSupport (completitud) - OUR DEFINITION: examples of the class compatibles / examples of the class
if (Examples.getExamplesClassObj() != 0)
csupport = ((float)ejCompAntClassFuzzy/Examples.getExamplesClassObj());
else
csupport = 0;
// Confidence - (Crisp): number of examples compatibles with antecedent and class / number examples compatibles with antecedent
if (ejCompAntCrisp != 0)
cconfianza = (float)ejCompAntClassCrisp/ejCompAntCrisp;
else
cconfianza = 0;
// fuzzy confidence - OUR DEFINITION (fuzzy): degree of compatibility with antecedent and class / degree of compatibility with antecedent
if (gradoCompAntFuzzy != 0)
confianza = (float)gradoCompAntClassFuzzy/gradoCompAntFuzzy;
else
confianza = 0;
// Accuracy
accuracy = (float)(ejCompAntClassCrisp+1) / (ejCompAntCrisp + Variables.getNClass());
//Coverage
coverage = ((float)ejCompAntCrisp/Examples.getNEx());
// Significance
float sumaSignClase=0;
for (int j=0; j<Variables.getNClass(); j++) {
if (cubreClase[j]!=0)
sumaSignClase += cubreClase[j] * Math.log10 ((float)cubreClase[j]/(ejClase[j]*coverage));
}
significance = 2 * sumaSignClase;
if (numVarNoInterv >= Variables.getNVars())
significance = 0;
// Unusualness
if (ejCompAntCrisp==0)
unusualness = 0;
else
unusualness = coverage * ( (float)ejCompAntClassCrisp/ejCompAntCrisp - (float)Examples.getExamplesClassObj()/Examples.getNEx());
if (numVarNoInterv >= Variables.getNVars())
unusualness = 0;
// Measures are set to 0 if no variable takes part in the rule (empty rule)
if (numVarNoInterv >= Variables.getNVars()) {
csupport = confianza = 0;
fsupport = support = cconfianza = 0;
accuracy = coverage = significance = unusualness = 0;
for (int x=0; x<Examples.getNEx(); x++)
cubre[x] = false; // The individual does not cover any example
}
// Set the individual as evaluated
evaluado = true;
// Store the quality measures
medidas.setFCnf(confianza);
medidas.setCCnf(cconfianza);
medidas.setCSup(support);
medidas.setFSup(fsupport);
medidas.setComp(csupport);
medidas.setAccu(accuracy);
medidas.setCove(coverage);
medidas.setSign(significance);
medidas.setUnus(unusualness);
// Store the values of the objectives from the measures computed
medidas.loadObjValues();
}
/**
* <p>
* Method to print the contents of the individual
* </p>
* @param nFile File to write the individual
*/
public void Print(String nFile) {
String contents;
cromosoma.print(nFile);
contents = "Fitness "+medidas.getFitness() + "\n";
contents+= "Evaluated? " + evaluado + "\n";
if (nFile=="")
System.out.print (contents);
else
Files.addToFile(nFile, contents);
}
}