/***********************************************************************
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.Rule_Learning.ART;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
/**
A Java implementation of the TBAR algorithm
@author Ines de la Torre Quesada (UJA)
@version 1.0 (28-02-2010)
*/
public class TBAR {
int MaxSize;
double MinSupp;
Vector data;
List<Attribute> attributes;
Node root;
Vector<Node> nodosNivel;
/** Constructor que crea e inicializa el arbol con los candidatos de nivel 1*/
public TBAR(int MaxSize, double MinSupp, Vector data, List<Attribute> attributes) {
this.MaxSize = MaxSize;
this.MinSupp = MinSupp;
this.data = data;
this.attributes = attributes;
root = new Node();
Vector nodes = new Vector();
for(int i=0; i<this.attributes.size()-1; i++){
Attribute a = this.attributes.get(i);
for(int j = 0; j<a.numValues(); j++){
Node n = new Node();
Vector<Integer> ats = new Vector<Integer>();
Vector<Integer> vals = new Vector<Integer>();
ats.add(i);
vals.add(j);
n.setAttributes(ats);
n.setValues(vals);
n.setParent(root);
nodes.add(n);
}
}
root.setChildren(nodes);
support(1);
}
public int getMaxSize() {
return MaxSize;
}
public void setMaxSize(int MaxSize) {
this.MaxSize = MaxSize;
}
public double getMinSupp() {
return MinSupp;
}
public void setMinSupp(double MinSupp) {
this.MinSupp = MinSupp;
}
public Vector getData() {
return data;
}
public void setData(Vector data) {
this.data = data;
}
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
private void support(int level){
Itemset item;
Node node = null;
nodosNivel = new Vector();
nodosNivel(level,root);
for(int i=0; i<data.size(); i++){
item = (Itemset)data.get(i);
for(int j = 0; j<nodosNivel.size(); j++){
node = nodosNivel.get(j);
if(coincide(node,item,level))
node.setSupport(node.getSupport()+1);
}
}
}
private void nodosNivel(int level, Node n){
if(level-1 > 0){
for(int i = 0; i<n.numChildren(); i++){
nodosNivel(level-1,n.getChildren(i));
}
}else{ //Estamos en el nivel que deseamos
for(int i = 0; i< n.numChildren(); i++){
nodosNivel.add(n.getChildren(i));
}
}
}
private boolean coincide(Node n, Itemset item, int level){
boolean ok;
int atributo;
if(level-1>0){
if (n.getAttributes().size() > 0) {
atributo = n.getAttributes().get(0);
if(item.getValue(atributo)==n.getValues().get(0)) ok = true;
else ok = false;
} else {
ok = false;
}
return(ok && coincide(n.getParent(),item,level-1));
}else{
if (n.getAttributes().size() > 0) {
atributo = n.getAttributes().get(0);
if(item.getValue(atributo)==n.getValues().get(0)) ok = true;
else ok = false;
} else {
ok = false;
}
return(ok);
}
}
private Vector candidates(int level){
Vector<Node> nivel1 = new Vector();
nodosNivel = new Vector();
nodosNivel(1,root);
nivel1 = (Vector)nodosNivel.clone();
nodosNivel = new Vector();
nodosNivel(level-1,root);
for(int i=0; i<nodosNivel.size(); i++){
expandir(nodosNivel.get(i),nivel1);
}
support(level);
nodosNivel = new Vector();
nodosNivel(level,root);
return nodosNivel;
}
private void expandir(Node n, Vector<Node> nivel1){
Vector nodes = new Vector();
Node nivel;
int i = 0;
while(i < nivel1.size()){
nivel = nivel1.get(i);
if(nivel.getAttributes().get(0)>n.getAttributes().get(0)){
Node node = new Node();
Vector<Integer> ats = new Vector<Integer>();
Vector<Integer> vals = new Vector<Integer>();
ats.add(nivel.getAttributes().get(0));
vals.add(nivel.getValues().get(0));
node.setAttributes(ats);
node.setValues(vals);
node.setParent(n);
nodes.add(node);
}
i++;
}
n.setChildren(nodes);
}
private Vector relevants(int level){
double supp;
nodosNivel = new Vector();
nodosNivel(level,root);
Vector nodos = new Vector(nodosNivel);
for(int i=0; i<nodosNivel.size(); i++){
Node n = nodosNivel.get(i);
supp = (double)n.getSupport()/data.size();
if(supp < MinSupp){
nodos.remove(n);
n.getParent().getChildren().remove(n);
}
}
return nodos;
}
public Vector<Vector<Rule>> ruleExtraction(int level){
Vector<Vector<Rule>> conjuntos = new Vector();
Vector<Rule> reglas = new Vector();
Vector<Rule> reglasConfMax = new Vector();
Vector<Node> nodos = new Vector();
nodos = relevants(1);
int k = 2;
while(k <= level && nodos.size() >= k){
nodos = candidates(k);
if(nodos.size()>0) nodos = relevants(k);
k++;
}
//Construir reglas con los atributos relevantes y obtener su confianza
int sum = 0;
Vector<Itemset> itemsets = new Vector();
Vector<Integer> ats = new Vector();
Vector<Integer> vals = new Vector();
for(int i=0; i<nodos.size(); i++){
Node n = nodos.get(i);
itemsets = new Vector();
ats = new Vector();
vals = new Vector();
while(n.getParent()!=null){
ats.add(n.getAttributes().get(0));
vals.add(n.getValues().get(0));
n = n.getParent();
}
Collections.reverse(ats);
Collections.reverse(vals);
for(int j=0; j<data.size(); j++){
if(coincide(nodos.get(i),(Itemset)data.get(j), level)){
itemsets.add((Itemset)data.get(j));
}
}
Attribute a = attributes.get(MaxSize);
for(int l=0; l<a.numValues(); l++){
sum = 0;
for(int m=0; m<itemsets.size(); m++){
Itemset it = itemsets.get(m);
if(it.getValue(MaxSize)==l) sum++;
}
Rule r = new Rule(ats,vals);
r.setClas(l);
r.setConfidence((double)sum/itemsets.size());
r.setSupport(sum);
reglas.add(r);
}
}
double confMax = 0;
//Obtener confianza maxima
for(int i=0; i<reglas.size(); i++){
if(reglas.get(i).getConfidence()>confMax){
confMax = reglas.get(i).getConfidence();
}
}
//Obtener las reglas con confianza maxima
for(int i=0; i<reglas.size(); i++){
if(reglas.get(i).getConfidence() == confMax){
reglasConfMax.add(reglas.get(i));
}
}
//Obtener conjuntos de reglas
Vector<Rule> conjunto = new Vector();
if(reglasConfMax.size()>0){
conjunto.add(reglasConfMax.get(0));
ats = new Vector(reglasConfMax.get(0).getAttributes());
}
for(int i=1; i<reglasConfMax.size(); i++){
if(!ats.equals(reglasConfMax.get(i).getAttributes())){ //no coincide
conjuntos.add(conjunto);
conjunto = new Vector();
conjunto.add(reglasConfMax.get(i));
ats = new Vector(reglasConfMax.get(i).getAttributes());
}else{
conjunto.add(reglasConfMax.get(i));
}
}
if(conjunto.size()!=0) conjuntos.add(conjunto);
return conjuntos;
}
}