/***********************************************************************
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/
**********************************************************************/
package keel.Algorithms.UnsupervisedLearning.AssociationRules.IntervalRuleLearning.MODENAR;
/**
* <p>
* @author Written by Diana Mart�n (dmartin@ceis.cujae.edu.cu)
* @version 1.1
* @since JDK1.6
* </p>
*/
import java.util.*;
import java.io.PrintWriter;
import java.lang.Math;
import java.math.BigDecimal;
import org.core.*;
public class MODENARProcess {
myDataset ds;
private String paretos;
private ArrayList<Chromosome> bestRules;
private ArrayList<AssociationRule> assoc_rules_Pareto;
//parameters
int nGeneration;
private int nEvaluations;
private int nRealEvaluations;
int popSize;
double CR;//crossover rate
int threshold;
double[]Wk;// weight for each fitness
private double allow_ampl[];
int max_rank;
public MODENARProcess() {
// TODO Auto-generated constructor stub
}
public MODENARProcess(myDataset ds, int nEvaluations, int popSize, double cr, int threshold, double[] wk, double AF) {
this.ds = ds;
this.popSize = popSize;
this.CR = cr;
this.threshold = threshold;
this.Wk = wk;
this.nEvaluations = nEvaluations;
this.paretos = new String("");
this.allow_ampl = new double[this.ds.getnVars()];
for (int i=0; i < this.allow_ampl.length; i++) this.allow_ampl[i] = (this.ds.getMax(i) - this.ds.getMin(i)) / (double) AF;
}
public void run()
{
//main fuction algorithm
int nGen,count;
Chromosome chromo_mutate, chromo_trial,chromo_select, parentChromo;
ArrayList<Chromosome> pop_new = new ArrayList<Chromosome>();
ArrayList<Chromosome> mutate_parentChromo;
this.paretos = new String("");
this.nRealEvaluations = 0;
nGen = 0;
System.out.println("Initialization");
ArrayList<Chromosome> pop = this.initialize();
while(!terminate()){
System.out.println("Generation: " + nGen);
count = 0;
pop = this.remove_dominate_solut(pop);
if(pop.size()>this.threshold){
pop = this.filtrating(pop);
}
pop_new = new ArrayList<Chromosome>();
while(pop_new.size()<popSize){
mutate_parentChromo = this.mutate(pop);
parentChromo = mutate_parentChromo.get(0).copy();
chromo_mutate = mutate_parentChromo.get(1).copy();
chromo_mutate = this.reparing(chromo_mutate).copy();
chromo_trial = new Chromosome();
chromo_trial = this.crossover(chromo_mutate.copy(), parentChromo.copy()).copy();
chromo_select = this.select(chromo_trial, parentChromo).copy();
if(pop_new.size()!=0){
if(!equalChromotoPop(chromo_select, pop_new)) pop_new.add(chromo_select.copy());
else count++;
if(count> 15){
chromo_select = chromo_trial.copy();
if(!equalChromotoPop(chromo_select, pop_new)) pop_new.add(chromo_select.copy());
}
}
else pop_new.add(chromo_select.copy());
}
pop = AdjustIntervalPop(pop_new);
nGen++;
}
this.bestRules = pop;
this.assign_rank(this.bestRules);
this.genRules();
this.printPareto(this.assoc_rules_Pareto);
}
public boolean terminate()
{
//stop condition for the algorithm
if(this.nRealEvaluations >= this.nEvaluations) return true;
return false;
}
private ArrayList<Chromosome> initialize()
{
ArrayList<Chromosome> popInit = new ArrayList<Chromosome>();
Chromosome c;
int count = 0;
while ((popInit.size() < this.popSize) && (count <100)){
c = this.generateRandomChromo().copy();
if(popInit.size()!=0){
if((!equalChromotoPop(c, popInit))&& (c.getFitness()[0]> 0.0)) {
popInit.add(c);
count = 0;
}
else count++;
}
else
if(c.getFitness()[0]> 0.0){
popInit.add(c);
count = 0;
}
else count++;
}
while (popInit.size() < this.popSize) {
c = this.generateChromoWithSupport().copy();
popInit.add(c);
}
return popInit;
}
private Chromosome generateRandomChromo()
{
int nVars, attr;
double lb, ub, max_attr, min_attr;
nVars = this.ds.getnVars();
ArrayList<Gene> genes = new ArrayList<Gene>();
for(int g=0;g<nVars;g++){
Gene gen = new Gene();
attr = g;
gen.setAttr(attr);
gen.setType(this.ds.getAttributeType(attr));
gen.setCa(Randomize.RandintClosed(0,2));
max_attr = this.ds.getMax(attr);
min_attr = this.ds.getMin(attr);
if ( gen.getType() != Gene.NOMINAL ) {
if ( gen.getType() == Gene.REAL ) {
lb = Randomize.RanddoubleClosed(min_attr, max_attr);
ub = Randomize.RanddoubleClosed(min_attr, max_attr);
}
//type is INTENGER
else {
lb = Randomize.RandintClosed((int) min_attr, (int) max_attr);
ub = Randomize.RandintClosed((int) min_attr, (int) max_attr);
}
}
else
lb = ub = Randomize.RandintClosed((int) min_attr, (int) max_attr);
if(lb <= ub){
gen.setL(lb);
gen.setU(ub);
}
else{
gen.setL(ub);
gen.setU(lb);
}
genes.add(gen.copy());
}
//ensure that it has at least one antecedent and consequent
int set_antec = Randomize.Randint(0, genes.size());
int set_cons = Randomize.Randint(0, genes.size());
while(set_antec == set_cons) set_cons = Randomize.Randint(0,genes.size());
genes.get(set_antec).setCa(0);
genes.get(set_cons).setCa(1);
Chromosome c = new Chromosome(genes);
c.setFitness(this.evaluate_chromosome(c));
return c;
}
private Chromosome generateChromoWithSupport()
{
int nVars, attr,tr;
double lb, ub, max_attr, min_attr;
nVars = this.ds.getnVars();
ArrayList<Gene> genes = new ArrayList<Gene>();
double[][] trans = this.ds.getRealTransactions();
tr = Randomize.Randint(0, this.ds.getnTrans());
for (int g=0; g < nVars; g++) {
Gene gen = new Gene();
attr = g;
gen.setAttr(attr);
gen.setType( this.ds.getAttributeType(attr));
gen.setCa(Randomize.RandintClosed(0,2));
max_attr = this.ds.getMax(attr);
min_attr = this.ds.getMin(attr);
if ( gen.getType() != Gene.NOMINAL ) {
if ( gen.getType() == Gene.REAL ) {
lb = Math.max(trans[tr][attr] - (this.allow_ampl[attr] / 2.0), min_attr);
ub = Math.min(trans[tr][attr] + (this.allow_ampl[attr] / 2.0), max_attr);
}
else {
lb = Math.max(trans[tr][attr] - ((int) this.allow_ampl[attr] / 2), min_attr);
ub = Math.min(trans[tr][attr] + ((int) this.allow_ampl[attr] / 2), max_attr);
}
}
else lb = ub = trans[tr][attr];
gen.setL(lb);
gen.setU(ub);
genes.add(gen.copy());
}
int set_antec = Randomize.Randint(0,genes.size()-1);
genes.get(set_antec).setCa(0);
int set_cons = Randomize.Randint(0,genes.size()-1);
while(set_antec == set_cons)
set_cons = Randomize.Randint(0,genes.size()-1);
genes.get(set_cons).setCa(1);
Chromosome c = new Chromosome(genes);
c.setFitness(this.evaluate_chromosome(c));
return c;
}
private Chromosome select(Chromosome trialChromo, Chromosome parentChromo)
{
//select between these chromosome: if one dominate the other one or not,
//if they do not dominate each other then select the solution
//calculating the sum of the weights
Chromosome dominChromo = new Chromosome();
int dominanc = Dominance(trialChromo,parentChromo);
if(dominanc!= 0)
if(dominanc == 1)
dominChromo = trialChromo.copy() ;
else
dominChromo = parentChromo.copy();
else
dominChromo = SelectByWeightedFitness(trialChromo,parentChromo);
return dominChromo;
}
private Chromosome crossover(Chromosome mutateChromo, Chromosome parentChromo)
{
//cross mutate and parent chromosome to get trial chromosome
int nVars, count;
nVars = this.ds.getnVars();
ArrayList<Gene> genes;
Chromosome trialChromo = new Chromosome();
boolean trialchromo_ok = false;
count = 0;
while (!trialchromo_ok){
genes = new ArrayList<Gene>();
for(int j=0;j < nVars; j++){
Gene gen = new Gene();
if((Randomize.Rand() < this.CR)||(j == Randomize.Randint(1,nVars)))
gen = mutateChromo.getGenes().get(j).copy();
else
gen = parentChromo.getGenes().get(j).copy();
genes.add(gen);
}
trialChromo = new Chromosome(genes);
int set_antec = Randomize.Randint(0,genes.size()-1);
genes.get(set_antec).setCa(0);
int set_cons = Randomize.Randint(0,genes.size()-1);
while(set_antec == set_cons)
set_cons = Randomize.Randint(0,genes.size()-1);
genes.get(set_cons).setCa(1);
trialChromo.setFitness(this.evaluate_chromosome(trialChromo));
if(trialChromo.getFitness()[0]> 0.0){
trialchromo_ok = true;
}
else count++;
if(count > 20){
trialchromo_ok = true;
trialChromo = generateChromoWithSupport();
}
}
return trialChromo;
}
private ArrayList<Chromosome> mutate(ArrayList<Chromosome>pop)
{
//return a mutate solution, this method uses three randomly solution selected
boolean allowmutate, allowmutateXb,allowmutateXc, mutatechromo_ok;
Chromosome Xi, Xa, Xb, Xc;
ArrayList<Chromosome> parent_mutate = new ArrayList<Chromosome>();;
int pos_i,pos_a,pos_b,pos_c, count;
mutatechromo_ok = false;
count=0;
while(!mutatechromo_ok){
allowmutate = false;
allowmutateXb = false;
allowmutateXc = false;
Xi = new Chromosome();
Xa = new Chromosome();
Xb = new Chromosome();
Xc = new Chromosome();
if(pop.size()<4){
if(pop.size()==3){
while(!allowmutate){
pos_i= Randomize.Randint(0,pop.size());
pos_a= Randomize.Randint(0,pop.size());
if(pos_i != pos_a){
Xi = pop.get(pos_i).copy();
Xa = pop.get(pos_a).copy();
allowmutate = true;
while(!allowmutateXb){
pos_b= Randomize.Randint(0,pop.size());
if((pos_i != pos_b) && (pos_a!= pos_b)){
allowmutateXb = true;
Xb = pop.get(pos_b).copy();
while(!allowmutateXc){
Xc = generateChromoWithSupport().copy();
if((!Xi.equals(Xc)) && (!Xa.equals(Xc))&&(!Xb.equals(Xc))){
allowmutateXc = true;
}
}
}
}
}
}
}
if(pop.size()==2){
while(!allowmutate){
pos_i= Randomize.Randint(0,pop.size());
pos_a= Randomize.Randint(0,pop.size());
if(pos_i != pos_a){
Xi = pop.get(pos_i).copy();
Xa = pop.get(pos_a).copy();
allowmutate = true;
while(!allowmutateXb){
Xb = generateChromoWithSupport().copy();
if((!Xi.equals(Xb)) && (!Xa.equals(Xb))){
allowmutateXb = true;
while(!allowmutateXc){
Xc = generateChromoWithSupport().copy();
if((!Xi.equals(Xc)) && (!Xa.equals(Xc))&&(!Xb.equals(Xc))){
allowmutateXc = true;
}
}
}
}
}
}
}
if(pop.size()==1){
while(!allowmutate){
Xi = pop.get(0).copy();
Xa = generateChromoWithSupport().copy();
if(!Xi.equals(Xa)){
allowmutate = true;
while(!allowmutateXb){
Xb = generateChromoWithSupport().copy();
if((!Xi.equals(Xb)) && (!Xa.equals(Xb))){
allowmutateXb = true;
while(!allowmutateXc){
Xc = generateChromoWithSupport().copy();
if((!Xi.equals(Xc)) && (!Xa.equals(Xc))&&(!Xb.equals(Xc))){
allowmutateXc = true;
}
}
}
}
}
}
}
}
else{
while(!allowmutate){
pos_i= Randomize.Randint(0,pop.size());
pos_a= Randomize.Randint(0,pop.size());
if(pos_i != pos_a){
Xi = pop.get(pos_i).copy();
Xa = pop.get(pos_a).copy();
allowmutate = true;
while(!allowmutateXb){
pos_b= Randomize.Randint(0,pop.size());
if((pos_i != pos_b) && (pos_a!= pos_b)){
allowmutateXb = true;
Xb = pop.get(pos_b).copy();
while(!allowmutateXc){
pos_c= Randomize.Randint(0,pop.size());
if((pos_i != pos_c) && (pos_a!= pos_c) && (pos_b!= pos_c)){
allowmutateXc = true;
Xc = pop.get(pos_c).copy();
}
}
}
}
}
}
}
Chromosome mutateXi = generateMutanteRandDE(Xi,Xa,Xb,Xc);
if(mutateXi.getFitness()[0]>0.0){
parent_mutate.add(Xi.copy());
parent_mutate.add(mutateXi.copy());
mutatechromo_ok = true;
count = 0;
}
else{
count++;
}
if(count > 15){
count = 0;
Xi = new Chromosome();
boolean allowmutateXi = false;
while(!allowmutateXi){
Xi = generateChromoWithSupport().copy();
if((!Xc.equals(Xi)) && (!Xa.equals(Xi))&&(!Xb.equals(Xi))){
allowmutateXi = true;
}
}
mutateXi = generateMutanteRandDE(Xi,Xa,Xb,Xc);
parent_mutate.add(Xi.copy());
parent_mutate.add(mutateXi.copy());
mutatechromo_ok = true;
}
}
return parent_mutate;
}
private Chromosome reparing(Chromosome chromo)
{
/*solves the problem of the interval values of the attributes that are created
at random after initialize the population or the mutation*/
double aux,L,U;
for(int i=0;i<chromo.getGenes().size();i++){
Gene gen = chromo.getGenes().get(i);
if(gen.getL()> gen.getU()){
aux = gen.getL();
gen.setL(gen.getU());
gen.setU(aux);
}
if(gen.getL() < ds.getMin(i)){
L= (gen.getL() + ds.getMin(i))/2;
gen.setL(L);
}
if(gen.getU() > ds.getMax(i)){
U= (gen.getU() + ds.getMax(i))/2;
gen.setU(U);
}
chromo.getGenes().set(i, gen);
}
return chromo;
}
private ArrayList<Chromosome> filtrating(ArrayList<Chromosome>pop)
{
//it used if the number of non-dominated solutions is greater than a certain threshold
ArrayList<Double> distEucAveList = new ArrayList<Double>();
ArrayList<Integer> posChromo = new ArrayList<Integer>();
ArrayList<Chromosome> chromo_List = new ArrayList<Chromosome>();
double minDist_i,minDist_j,distEuclid_x = 0,distEuclidAve_x = 0 ;
for(int i=0; i< pop.size();i++){
Chromosome chromo_x = pop.get(i);
minDist_i = DistanceEuclidea(pop.get(i),pop.get(1));
minDist_j = DistanceEuclidea(pop.get(i),pop.get(2));
for(int j=i+1;j < pop.size();j++){
Chromosome chromo_j = pop.get(j);
distEuclid_x = DistanceEuclidea(chromo_x, chromo_j);
if(distEuclid_x < minDist_i)
minDist_i = distEuclid_x;
else if(distEuclid_x < minDist_j)
minDist_j = distEuclid_x;
}
distEuclidAve_x = (minDist_i + minDist_j)/2;
boolean insert = false;
int k = 0;
if(distEucAveList.size()==0)
{
distEucAveList.add(0,distEuclidAve_x);
insert=true;
}
while((!insert) && (k < distEucAveList.size())){
if(distEuclidAve_x < distEucAveList.get(k)){
distEucAveList.add(k,distEuclidAve_x);
chromo_List.add(k,chromo_x);
posChromo.add(k, i);
insert = true;
}
else
{
distEucAveList.add(distEuclidAve_x);
posChromo.add(i);
chromo_List.add(chromo_x);
insert = true;
}
k++;
}
}
//remove chromosome until popsize = threshold
int l=0;
while(pop.size()> this.threshold){
//int posdelete = posChromo.get(l);
pop.remove(chromo_List.get(l));
//pop.remove(posdelete);
l++;
}
return pop;
}
private double[] evaluate_chromosome(Chromosome chromo) {
double[] fitness = new double[4];
double comprehensibility = 0, amplitudeInterv = 0;
AssociationRule rule = getRule(chromo);
fitness[0]= rule.getAll_support();
fitness[1]= rule.getConfidence();
comprehensibility = Math.log10(1 + rule.getAntecedent().size())/ Math.log10(1 + rule.getAntecedent().size() + rule.getConsequent().size());
fitness[2]= comprehensibility;
int countAttbRule = rule.getAntecedent().size() + rule.getConsequent().size();
double sumInterv = 0;
for(int i = 0;i<chromo.getGenes().size();i++){
Gene gen = chromo.getGenes().get(i);
if(gen.getCa()!= 2){
if(ds.getMax(i)- ds.getMin(i) != 0)
sumInterv = sumInterv + ((gen.getU()-gen.getL())/(ds.getMax(i)- ds.getMin(i)));
}
}
double div_countAttbRule= (1.0/countAttbRule);
amplitudeInterv = Math.abs(1-(div_countAttbRule*(sumInterv)));
fitness[3]= amplitudeInterv;
chromo.setRuleSupport(rule.getAll_support());
chromo.setRuleConfidence(rule.getConfidence());
this.nRealEvaluations++;
return fitness;
}
private ArrayList<Chromosome> remove_dominate_solut(ArrayList<Chromosome>pop)
{
for(int j=0; j< pop.size(); j++){
for(int k= j+1;k< pop.size();k++){
if(Dominance(pop.get(j), pop.get(k))== 1)// j domina k
pop.remove(k);
else if(Dominance(pop.get(j), pop.get(k))== -1){
pop.remove(j);
}
}
}
return pop;
}
/* 1 if a dominates b
-1 if b dominates a
0 if both a and b are non-dominated */
private int Dominance(Chromosome chromo_a, Chromosome chromo_b) {
int flag1 = 0, flag2 = 0;
for (int i=0; i<chromo_a.getFitness().length; i++) {
if (chromo_a.getFitness()[i] > chromo_b.getFitness()[i]) flag1 = 1;
else if (chromo_a.getFitness()[i] < chromo_b.getFitness()[i]) flag2 = 1;
}
if ((flag1 == 1) && (flag2 == 0)) return (1);
else if (flag1 == 0 && flag2 == 1) return (-1);
else return (0);
}
private Chromosome SelectByWeightedFitness(Chromosome chromo1, Chromosome chromo2)
{
//it implements the function for weighted sum fitness in order to decide the chr that will be selected
//if none dominates another
if(calculate_WeightedFitness(chromo1)> calculate_WeightedFitness(chromo2))
return chromo1;
else
return chromo2;
}
private double calculate_WeightedFitness(Chromosome chromo)
{
double weightChromo = 0;
for(int i=0; i< chromo.getFitness().length; i++){
weightChromo = weightChromo + Wk[i] * chromo.getFitness()[i];
}
return weightChromo;
}
private ArrayList<Chromosome> AdjustIntervalPop(ArrayList<Chromosome> pop)
{
for(int i=0; i< pop.size();i++){
pop.set(i, AdjustIntervalChromo(pop.get(i)));
}
return pop;
}
private Chromosome AdjustIntervalChromo(Chromosome chromo)
{
ArrayList<Integer> tid_list = new ArrayList<Integer>();
double[][] examples = ds.getRealTransactions();
int attr;
double minlb, maxub;
tid_list = this.countSupport(chromo.getGenes());
if(tid_list.size()!=0)
{
for (int g=0; g < chromo.getGenes().size(); g++)
{
attr = chromo.getGenes().get(g).getAttr();
minlb = examples[tid_list.get(0)][attr];
maxub = examples[tid_list.get(0)][attr];
for (int t=1; t < tid_list.size(); t++) {
if (examples[tid_list.get(t)][attr] < minlb)
minlb = examples[t][attr];
if(examples[t][attr] > maxub){
maxub = examples[t][attr];
}
}
chromo.getGenes().get(g).setL(minlb);
chromo.getGenes().get(g).setU(maxub);
}
}
return chromo;
}
private Chromosome generateMutanteRandDE(Chromosome Xi, Chromosome Xa,Chromosome Xb, Chromosome Xc)
{
// Xi = Xa + F(Xb-Xc)
double genL=0,genU=0;
int count;
boolean allowed_gen;
Chromosome mutateChromo = new Chromosome();
mutateChromo = Xi.copy();
for(int i = 0; i< ds.getnVars(); i++){
Gene gen = mutateChromo.getGenes().get(i);
allowed_gen = false;
count = 0;
while(!allowed_gen){
if ( gen.getType() != Gene.NOMINAL ) {
if(gen.getType()== Gene.REAL){
genL = Math.abs(Xa.getGenes().get(i).getL() + Randomize.RandGaussian()*(Xb.getGenes().get(i).getL()- Xc.getGenes().get(i).getL()));
genU =Math.abs(Xa.getGenes().get(i).getU() + Randomize.RandGaussian()*(Xb.getGenes().get(i).getU()- Xc.getGenes().get(i).getU()));
}
if(gen.getType()== Gene.INTEGER){
genL = Math.abs(Xa.getGenes().get(i).getL() + Math.round(Randomize.RandGaussian()*(Xb.getGenes().get(i).getL()- Xc.getGenes().get(i).getL())));
genU = Math.abs(Xa.getGenes().get(i).getU() + Math.round(Randomize.RandGaussian()*(Xb.getGenes().get(i).getU()- Xc.getGenes().get(i).getU())));
}
}
else
genL = genU = Randomize.RandintClosed((int)this.ds.getMin(Xa.getGenes().get(i).getAttr()), (int)this.ds.getMax(Xa.getGenes().get(i).getAttr()));
if(genL > genU){
double aux = genL;
genL = genU;
genU = aux;
}
if(genL >= this.ds.getMin(i)&&(genU <= this.ds.getMax(i)))allowed_gen = true;
else count ++;
if(count > 15){
allowed_gen = true;
if(gen.getL() < ds.getMin(i)){
genL= (gen.getL() + ds.getMin(i))/2;
}
if(gen.getU() > ds.getMax(i)){
genU= (gen.getU() + ds.getMax(i))/2;
}
}
mutateChromo.getGenes().get(i).setL(genL);
mutateChromo.getGenes().get(i).setU(genU);
}
}
/*for(int i=0;i< mutateChromo.getGenes().size();i++){
mutateChromo.getGenes().get(i).setCa(Randomize.RandintClosed(0,2));
}*/
mutateChromo.setFitness(evaluate_chromosome(mutateChromo));
return mutateChromo;
}
/**
* @param chromo
* @return
*/
private AssociationRule getRule(Chromosome chromo)
{
int j;
double all_sup, ant_sup, cons_sup, confidance, nData;
ArrayList<Integer> tid_lst_all, tid_lst_ant, tid_lst_cons;
AssociationRule rule;
ArrayList<Gene> genes_ant;
ArrayList<Gene> genes_cons;
ArrayList<Gene> genes_all;
nData=(double)this.ds.getnTrans();
rule = new AssociationRule();
genes_ant = new ArrayList<Gene>();
genes_cons = new ArrayList<Gene>();
genes_all = new ArrayList<Gene>();
for (j=0; j < this.ds.getnVars(); j++) {
if(chromo.getGenes().get(j).getCa()== 0){
rule.addAntecedent(chromo.getGenes().get(j).copy());
genes_ant.add(chromo.getGenes().get(j));
genes_all.add(chromo.getGenes().get(j));
}
if(chromo.getGenes().get(j).getCa()== 1){
rule.addConsequent(chromo.getGenes().get(j).copy());
genes_cons.add(chromo.getGenes().get(j));
genes_all.add(chromo.getGenes().get(j));
}
}
tid_lst_all = this.countSupport(genes_all);
all_sup = (double) tid_lst_all.size() / nData;
tid_lst_ant = this.countSupport(genes_ant);
ant_sup = (double) tid_lst_ant.size() / nData;
tid_lst_cons = this.countSupport(genes_cons);
cons_sup = (double) tid_lst_cons.size() / nData;
if ((ant_sup == 0.0) || (all_sup == 0.0)) confidance = 0.0;
else confidance = all_sup / ant_sup;
rule.setSupport(ant_sup);
rule.setAll_support(all_sup);
rule.setSupport_consq(cons_sup);
rule.setConfidence (confidance);
return rule;
}
private int numCoveredRecords () {
int i, j, covered, nTrans;
ArrayList<Integer> tidCovered;
ArrayList<Gene> genes_all;
Chromosome chromo;
nTrans = this.ds.getnTrans();
boolean [] marked = new boolean[nTrans];
for (i=0; i < nTrans; i++) marked[i] = false;
for (i=0; i < this.bestRules.size(); i++) {
chromo = this.bestRules.get(i);
genes_all = new ArrayList<Gene>();
for (int k=0; k < this.ds.getnVars(); k++) {
if(chromo.getGenes().get(k).getCa()!= 2){
genes_all.add(chromo.getGenes().get(k));
}
}
if(chromo.rank < 2){
tidCovered = this.countSupport(genes_all);
for (j=0; j < tidCovered.size(); j++) marked[tidCovered.get(j)] = true;
}
}
covered = 0;
for (i=0; i < nTrans; i++)
if (marked[i]) covered++;
return covered;
}
private void genRules() {
int i, j;
double yulesQ, numeratorYules, denominatorYules, all_sup, ant_sup, cons_sup, lift, confidance, nData, conv, CF, netConf;
ArrayList<Integer> tid_lst_all, tid_lst_ant, tid_lst_cons;
AssociationRule rule;
Chromosome chromo;
ArrayList<Gene> genes_ant;
ArrayList<Gene> genes_cons;
ArrayList<Gene> genes_all;
nData=(double)this.ds.getnTrans();
this.assoc_rules_Pareto = new ArrayList<AssociationRule>();
for (i=0; i < this.bestRules.size(); i++) {
chromo = bestRules.get(i);
if(chromo.rank < 2) {
rule = new AssociationRule();
genes_ant = new ArrayList<Gene>();
genes_cons = new ArrayList<Gene>();
genes_all = new ArrayList<Gene>();
for (j=0; j < this.ds.getnVars(); j++) {
if(chromo.getGenes().get(j).getCa()== 0){
rule.addAntecedent(chromo.getGenes().get(j).copy());
genes_ant.add(chromo.getGenes().get(j));
genes_all.add(chromo.getGenes().get(j));
}
if(chromo.getGenes().get(j).getCa()== 1){
rule.addConsequent(chromo.getGenes().get(j).copy());
genes_cons.add(chromo.getGenes().get(j));
genes_all.add(chromo.getGenes().get(j));
}
}
tid_lst_all = this.countSupport(genes_all);
all_sup = (double) tid_lst_all.size() / nData;
tid_lst_cons = this.countSupport(genes_cons);
cons_sup = (double) tid_lst_cons.size() / nData;
tid_lst_ant = this.countSupport(genes_ant);
ant_sup = (double) tid_lst_ant.size() / nData;
rule.setSupport(ant_sup);
rule.setSupport_consq(cons_sup);
rule.setAll_support(all_sup);
if(all_sup != 0)
confidance = all_sup / ant_sup;
else confidance = 0;
//compute lift
if((cons_sup == 0) || (ant_sup == 0))
lift = 1;
else lift = all_sup / (ant_sup*cons_sup);
//compute conviction
if((cons_sup == 1)||(ant_sup == 0))
conv = 1;
else conv = (ant_sup*(1-cons_sup))/(ant_sup-all_sup);
//compute netconf
if((ant_sup == 0)||(ant_sup == 1)||(Math.abs((ant_sup * (1-ant_sup))) <= 0.001))
netConf = 0;
else netConf = (all_sup - (ant_sup*cons_sup))/(ant_sup * (1-ant_sup));
//compute yulesQ
numeratorYules = ((all_sup * (1 - cons_sup - ant_sup + all_sup)) - ((ant_sup - all_sup)* (cons_sup - all_sup)));
denominatorYules = ((all_sup * (1 - cons_sup - ant_sup + all_sup)) + ((ant_sup - all_sup)* (cons_sup - all_sup)));
if((ant_sup == 0)||(ant_sup == 1)|| (cons_sup == 0)||(cons_sup == 1)||(Math.abs(denominatorYules) <= 0.001))
yulesQ = 0;
else yulesQ = numeratorYules/denominatorYules;
//compute Certain Factor(CF)
CF = 0;
if(confidance > cons_sup)
CF = (confidance - cons_sup)/(1-cons_sup);
else
if(confidance < cons_sup)
CF = (confidance - cons_sup)/(cons_sup);
rule.setConfidence (confidance);
rule.setLift(lift);
rule.setConv(conv);
rule.setCF(CF);
rule.setNetConf(netConf);
rule.setYulesQ(yulesQ);
rule.setComprehensibility(chromo.getFitness()[2]);
rule.setAmplitudeInterv(chromo.getFitness()[3]);
this.assoc_rules_Pareto.add(rule);
}
}
}
private ArrayList<Integer> countSupport(ArrayList<Gene> genes) {
ArrayList<Integer> tid_list = new ArrayList<Integer>();
double[][] trans = this.ds.getRealTransactions();
int attr, nTrans;
double lb, ub;
boolean ok;
nTrans = this.ds.getnTrans();
for (int t=0; t < nTrans; t++) {
ok = true;
for (int g=0; g < genes.size() && ok; g++) {
attr = genes.get(g).getAttr();
lb = genes.get(g).getL();
ub = genes.get(g).getU();
if ((trans[t][attr] < lb) || (trans[t][attr] > ub)) ok = false;
}
if (ok) tid_list.add(t);
}
return tid_list;
}
private double DistanceEuclidea(Chromosome chromo_a,Chromosome chromo_b)
{
double DistEuclidea,lb_a,ub_a,lb_b,ub_b;
double suma_lb_ub = 0,suma = 0, resta_lb,resta_ub;
for(int i=0; i< chromo_a.getGenes().size();i++){
lb_a = chromo_a.getGenes().get(i).getL();
ub_a = chromo_a.getGenes().get(i).getU();
lb_b = chromo_b.getGenes().get(i).getL();
ub_b = chromo_b.getGenes().get(i).getU();
resta_lb = lb_a - lb_b;
resta_ub = ub_a - ub_b;
suma_lb_ub = resta_lb + resta_ub;
suma = suma + Math.pow(suma_lb_ub,2);//aplicando la sumatoria del cuadrado
}
DistEuclidea = Math.sqrt(suma);
return DistEuclidea;
}
private boolean equalChromotoPop(Chromosome chromo_a, ArrayList<Chromosome> pop){
boolean equal_chr = false;
int i=0;
while((!equal_chr)&&(i<pop.size())){
if(chromo_a.equals(pop.get(i)))
equal_chr = true;
i++;
}
return equal_chr;
}
public ArrayList<Chromosome> getBestrules() {
return bestRules;
}
public void setBestrules(ArrayList<Chromosome> bestrules) {
this.bestRules = bestrules;
}
public double getCR() {
return CR;
}
public void setCR(double cr) {
CR = cr;
}
public myDataset getDs() {
return ds;
}
public void setDs(myDataset ds) {
this.ds = ds;
}
public int getPopSize() {
return popSize;
}
public void setPopSize(int popSize) {
this.popSize = popSize;
}
public int getThreshold() {
return threshold;
}
public void setThreshold(int threshold) {
this.threshold = threshold;
}
public double[] getWk() {
return Wk;
}
public void setWk(double[] wk) {
this.Wk = wk;
}
public static double roundDouble(double number, int decimalPlace){
double numberRound;
if(!Double.isInfinite(number)&&(!Double.isNaN(number))){
BigDecimal bd = new BigDecimal(number);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_UP);
numberRound = bd.doubleValue();
return numberRound;
}else return number;
}
public void saveReport (ArrayList<AssociationRule> rules, PrintWriter w ) {
int i, countRules, length;
AssociationRule rule;
double avg_yulesQ, avg_sup, avg_conf, avg_lift,avg_conv, avg_CF, avg_netConf;
countRules = length = 0;
avg_yulesQ = avg_sup = avg_conf = avg_lift = avg_conv = avg_CF = avg_netConf = 0.0;
for (i=0; i < rules.size(); i++) {
rule = rules.get(i);
countRules++;
length += (rule.getLengthAntecedent()+ rule.getLengthConsequent());
avg_sup += rule.getAll_support();
avg_conf += rule.getConfidence();
avg_lift += rule.getLift();
avg_conv += rule.getConv();
avg_CF += rule.getCF();
avg_netConf += rule.getNetConf();
avg_yulesQ += rule.getYulesQ();
}
w.println("\nNumber of Frequent Itemsets found: " + "-");
System.out.println("\nNumber of Frequent Itemsets found: " + "-");
w.println("\nNumber of Association Rules generated: " + countRules);
System.out.println("Number of Association Rules generated: " + countRules);
if (countRules!=0 ){
w.println("Average Support: " + roundDouble(( avg_sup / countRules ), 2));
System.out.println("Average SupportRules: " + roundDouble(( avg_sup / countRules ), 2) );
w.println("Average Confidence: " + roundDouble(( avg_conf / countRules ), 2));
System.out.println("Average Confidence: " + roundDouble(( avg_conf / countRules ), 2) );
w.println("Average Lift: " + roundDouble(( avg_lift / countRules ), 2));
System.out.println("Average Lift: " + roundDouble(( avg_lift / countRules ), 2) );
w.println("Average Conviction: " + roundDouble(( avg_conv/ countRules ), 2));
System.out.println("Average Conviction: " + roundDouble(( avg_conv/ countRules ), 2));
w.println("Average Certain Factor: " + roundDouble(( avg_CF/ countRules ), 2));
System.out.println("Average Certain Factor: " + roundDouble(( avg_CF/ countRules ), 2));
w.println("Average Netconf: " + roundDouble(( avg_netConf/ countRules), 2));
System.out.println("Average Netconf: " + roundDouble(( avg_netConf/ countRules), 2));
w.println("Average YulesQ: " + roundDouble(( avg_yulesQ/ countRules), 2));
System.out.println("Average yulesQ: " + roundDouble(( avg_yulesQ/ countRules), 2));
w.println("Average Number of Antecedents: " + roundDouble(( length / (double) countRules ),2));
System.out.println("Average Number of Antecedents: " + roundDouble(( length / (double) countRules ),2));
w.println("Number of Covered Records (%): " + roundDouble((100.0 * this.numCoveredRecords ()) / this.ds.getnTrans(), 2));
System.out.println("Number of Covered Records (%): " + roundDouble(( 100.0 * this.numCoveredRecords ()) / this.ds.getnTrans(),2));
}
else System.out.println("No Statistics.");
}
public void printPareto( ArrayList<AssociationRule> rulesPareto) {
int i;
AssociationRule rule;
this.paretos += ("Support\tantecedent_support\tconsequent_support\tConfidence\tLift\tConv\tCF\tNetConf\tYulesQ\tnAttributes\n");
for (i=0; i < this.assoc_rules_Pareto.size(); i++) {
rule = this.assoc_rules_Pareto.get(i);
this.paretos += ("" + roundDouble(rule.getAll_support(),2) + "\t" + roundDouble(rule.getSupport(),2) + "\t" + roundDouble(rule.getSupport_consq(),2) + "\t" + roundDouble(rule.getConfidence(),2) + "\t" + roundDouble(rule.getLift(),2) + "\t" + roundDouble(rule.getConv(),2) + "\t" + roundDouble(rule.getCF(),2) + "\t" + roundDouble(rule.getNetConf(),2) + "\t" + roundDouble(rule.getYulesQ(),2) + "\t" + (rule.getLengthAntecedent()+ rule.getLengthConsequent()) + "\n");
}
}
public String getParetos() {
return (this.paretos);
}
public ArrayList<AssociationRule> getAssoc_rules_Pareto() {
return assoc_rules_Pareto;
}
/**
* Function to assign rank to a population of size pop_size
* @param new_pop population
*/
private void assign_rank (ArrayList<Chromosome> new_pop){
int flag;
int i;
int end;
int front_size;
int rank=1;
Lists orig;
Lists cur;
Lists temp1, temp2;
orig = new Lists();
cur = new Lists();
front_size = 0;
//System.err.println ("Tama�a de new_pop = " + new_pop.size() + " Tama�o que deberia tener = " + this.uPopSize);
temp1 = orig;
for (i=0; i< new_pop.size(); i++) {
temp1.insert (temp1,i);
temp1 = temp1.child;
}
do {
if (orig.child.child == null) {
new_pop.get(orig.child.index).rank = rank;
break;
}
temp1 = orig.child;
temp1.insert (cur, temp1.index);
front_size = 1;
temp2 = cur.child;
temp1 = temp1.del (temp1);
temp1 = temp1.child;
do
{
temp2 = cur.child;
do
{
end = 0;
flag = Dominance(new_pop.get(temp1.index), new_pop.get(temp2.index));
if (flag == 1)
{
temp1.insert (orig, temp2.index);
temp2 = temp2.del (temp2);
front_size--;
temp2 = temp2.child;
}
if (flag == 0)
{
temp2 = temp2.child;
}
if (flag == -1)
{
end = 1;
}
} while (end!=1 && temp2!=null);
if (flag == 0 || flag == 1) {
temp1.insert (cur, temp1.index);
front_size++;
temp1 = temp1.del (temp1);
}
temp1 = temp1.child;
} while (temp1 != null);
temp2 = cur.child;
do {
new_pop.get(temp2.index).rank = rank;
temp2 = temp2.child;
} while (temp2 != null);
temp2 = cur.child;
do {
temp2 = temp2.del (temp2);
temp2 = temp2.child;
} while (cur.child !=null);
rank++;
} while (orig.child != null);
this.max_rank = rank;
return;
}
}