package keel.Algorithms.UnsupervisedLearning.AssociationRules.FuzzyRuleLearning.Fingrams; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class FARFingrams extends Fingrams { // /////////// VARIABLES ///////////// // List of supports of rules private List<Double> support; // List of confidences of rules private List<Double> confidence; // List of lifts of rules private List<Double> lift; private Double minSupport; private Double maxSupport; private Double minLift; private Double maxLift; // List of possible variables that can appear as conclusions. They can have // variables repeated, to correspond with the variable // possibleLabelConclusions private List<String> possibleVbleConclusions; // Matrix that stores the firingDegrees up to which the examples fire the // rules. Each row means a rule, each column the firingDegree of the // example j protected double[][] matrixFiringDegrees; // /////////// END VARIABLES ///////////// // /////////// METHODS ///////////// // // // // BUILDERS // // // // public FARFingrams() { super(); support = new ArrayList<Double>(); confidence = new ArrayList<Double>(); lift = new ArrayList<Double>(); minSupport = 0.0; maxSupport = 0.0; minLift = 0.0; maxLift = 0.0; possibleVbleConclusions = new ArrayList<String>(); ruleUncoveredExamples = false; numberUncoveredExamples = 0; uncoveredExamples = new ArrayList<Integer>(); } public FARFingrams(int typeRelation, String file) { super(typeRelation, file); support = new ArrayList<Double>(); confidence = new ArrayList<Double>(); lift = new ArrayList<Double>(); minSupport = 0.0; maxSupport = 0.0; minLift = 0.0; maxLift = 0.0; possibleVbleConclusions = new ArrayList<String>(); ruleUncoveredExamples = false; numberUncoveredExamples = 0; uncoveredExamples = new ArrayList<Integer>(); } // // // // GETS & SETS // // // // public List<Double> getSupport() { return support; } public List<Double> getConfidence() { return confidence; } public List<Double> getLift() { return lift; } public List<String> getPossibleVbleConclusions() { return possibleVbleConclusions; } public Double getMinSupport() { return minSupport; } public Double getMaxSupport() { return maxSupport; } public Double getMinLift() { return minLift; } public Double getMaxLift() { return maxLift; } public double[][] getFiringDegrees() { return matrixFiringDegrees; } // // // // ABSTRACT METHODS // // // // @Override public int loadInfoFromFS() { try { // Initializations this.numberAntecedents = new ArrayList<Integer>(); // Read the information of the 'file' and put into fileContent String fileContent = (new AdministrativeStaff()) .readFileAsString(fileLocation + ".fs"); // Split the entire file line by line. Blank lines are elminated List<String> line = Arrays.asList(fileContent.split("[\\r\\n]+")); // Split the second line, that contains variables and labels that // are as consequents, by '(', ')', ';', and ' ' List<String> outVblLabls = Arrays.asList(line.get(1).split( "[(); ]+")); //System.out.println("outVblLabls: "+outVblLabls+"; outVblLabls.size(): "+outVblLabls.size()); this.numberRules = Integer.parseInt(line.get(3).split("[: ]+")[1]); if (numberRules==0){ return 0; } for (int i = 0; i < outVblLabls.size(); i += 2) { List<String> outLabls = Arrays.asList(outVblLabls.get(i + 1) .split("[,]+")); for (int j = 0; j < outLabls.size(); j++) { possibleVbleConclusions.add(outVblLabls.get(i)); possibleLabelConclusions.add(outLabls.get(j)); } } // Save the number of rules present in the system read this.numberExamples = Integer .parseInt(line.get(4).split("[: ]+")[1]); this.matrixRulesXExamples = new byte[numberRules][numberExamples]; this.matrixFiringDegrees = new double[numberRules][numberExamples]; // int[] outClasses = new int[numberRules]; Double ruleSupport0 = Double.parseDouble(line.get(6).split( "(=>)[ ]+")[1].split("[() ]+")[2]); // antecedentSupport Double antecedentSupport0 = Double.parseDouble(line.get(7).split( "(=>)[ ]+")[1].split("[() ]+")[2]); // consequentSupport Double consequentSupport0 = Double.parseDouble(line.get(8).split( "(=>)[ ]+")[1].split("[() ]+")[2]); // Store the min and max support with the first rule minSupport = ruleSupport0; maxSupport = ruleSupport0; // Store the min and max lift with the first rule minLift = (ruleSupport0 / antecedentSupport0) / consequentSupport0; maxLift = (ruleSupport0 / antecedentSupport0) / consequentSupport0; for (int i = 0; i < numberRules; i += 1) { // Jumps over 4 lines every time int j = 5 + i * 4; String textRule = line.get(j); if (line.get(j).split(":")[1].toUpperCase().replaceAll(" ", "") .equals("UNCOVEREDEXAMPLES")) { ruleUncoveredExamples = true; numberUncoveredExamples = line.get(j + 1).split(",").length; for (String numberExample : Arrays.asList(line.get(j + 1) .split("(,)[ ]+"))) { uncoveredExamples.add(Integer.parseInt(numberExample)); } } else { rulesIdentifiers.add(line.get(j).split(":")[0]); // Obtain the information from file // totalruleSupport Double totalRuleSupport = Double .parseDouble(line.get(j + 1).split("(=>)[ ]+")[1] .split("[() ]+")[1]); // ruleSupport Double meanRuleSupport = Double.parseDouble(line.get(j + 1) .split("(=>)[ ]+")[1].split("[() ]+")[2]); // antecedentSupport Double meanAntecedentSupport = Double.parseDouble(line.get( j + 2).split("(=>)[ ]+")[1].split("[() ]+")[2]); // consequentSupport Double meanConsequentSupport = Double.parseDouble(line.get( j + 3).split("(=>)[ ]+")[1].split("[() ]+")[2]); // Stores the information // totalFiringDegrees totalFiringDegrees.add(totalRuleSupport); // support support.add(meanRuleSupport); // confidence confidence.add(support.get(i) / meanAntecedentSupport); // lift lift.add(confidence.get(i) / meanConsequentSupport); // System.out.println(rulesIdentifiers.get(i)+ " : "+ // lift.get(i)); int numberAntecedentsRule = new AdministrativeStaff() .countAntecedents(line.get(j).split("[ ]+")); String outVble = line.get(j).split("[ ]+")[line.get(j) .split("[ ]+").length - 3]; String outLabel = line.get(j).split("[ ]+")[line.get(j) .split("[ ]+").length - 1]; int h; for (h = 0; h < possibleLabelConclusions.size(); h++) { if (possibleVbleConclusions.get(h).equals(outVble) && possibleLabelConclusions.get(h).equals( outLabel)) { break; } } if (h == possibleLabelConclusions.size()) System.out .println("101 ERROR: Error treating the file " + fileLocation + " in vble " + outVble + " label " + outLabel); // List<Integer> listExamplesCoveredByActualRule = new // ArrayList<Integer>(); // List<Double> actualFiringDegree = new // ArrayList<Double>(); // Load rule support String first = Arrays .asList(line.get(j + 1).split("(=>)[ ]+")[2] .split("[, ]+")).get(0); if (first.contains("There")) { } else { for (String aux : Arrays.asList(line.get(j + 1).split( "(=>)[ ]+")[2].split("[, ]+"))) { int numberExample = Integer.parseInt(aux .split("[(]")[0]); Double valueFiring = Double.parseDouble(aux .split("[()]")[1]); // listExamplesCoveredByActualRule.add(Integer.parseInt(numberExample)); // actualFiringDegree.add(valueFiring); matrixRulesXExamples[i][numberExample] = 1; matrixFiringDegrees[i][numberExample] = valueFiring; } } if (minSupport > meanRuleSupport) minSupport = meanRuleSupport; if (maxSupport < meanRuleSupport) maxSupport = meanRuleSupport; if (minLift > lift.get(i)) minLift = lift.get(i); if (maxLift < lift.get(i)) maxLift = lift.get(i); // listExamplesCoveredByRule.add(listExamplesCoveredByActualRule); // firingDegrees.add(actualFiringDegree); numberAntecedents.add(numberAntecedentsRule); textRules.add(textRule); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return numberRules; } @Override public InfoNode calculateInfoNode(int n) { DecimalFormat df = (new AdministrativeStaff()).format(); String nodeInfo = "R" + rulesIdentifiers.get(n).substring(4) + "\\n" + " (sup=" + df.format(support.get(n)) + ") \\n" + " (conf=" + df.format(confidence.get(n)) + ") \\n (lift=" + df.format(lift.get(n)) + ")"; String nodeInfoToolTipText = this.textRules.get(n) + " (sup=" + df.format(support.get(n)) + "; conf=" + df.format(confidence.get(n)) + "; lift=" + df.format(lift.get(n)) + ")"; int ind = 100 - (int) ((lift.get(n) - minLift) * (100 / (maxLift - minLift))); /* * if (lift.get(n)>2.0) { * System.out.println(this.textRules.get(n)+" ("+lift.get(n)+")"); }// */ String nodeColor = "grey" + String.valueOf(ind); String borderColor = nodeColor; if (borderColor.equals("grey100")) borderColor = "grey0"; // Set the font color String fontColor = "black"; if (ind <= 50) fontColor = "white"; // Calculate the size of the node according to its support double nodeSize = 1 + 10 * ((double) (support.get(n) - minSupport) / (double) (maxSupport - minSupport)); // Set the font size float fontSize = 10 + 1.8f * ((int) nodeSize); InfoNode in = new InfoNode(nodeInfo, nodeInfoToolTipText, nodeSize, nodeColor, borderColor, fontSize, fontColor); return in; } // // // // OVERRIDE METHODS // // // // @Override /* * public void generateMatrix() { if (typeRelation == 0) { * super.generateUndirectedMatrix(); } else { if (typeRelation == 1) { * generateDirectedMatrix(); } } } */ /* * function generateDirectedMatrix * * mij=1-(\frac{\sum_{x \in X} |FDi(x)-FDj(x)|}{\sum_{x \in X} FDi(x)} * * being x the examples that fires rules i and FDi(x) the level up to which * the example x fires the rule i. Note that if an example z does not fire a * rule j, FDj(z)=0 * * Need: The list of examples covered by each rule Produce: Nothing Modify: * The matrix socialNetwork with the iteration between rules */ protected void generateDirectedMatrix() { socialNetwork = new ArrayList<List<Double>>(numberRules); // List<Float> totalFiringDegrees = new ArrayList<Float>(); // Create the identity matrix in result /* * for (int i = 0; i < numberRules; i++) { socialNetwork.add(new * ArrayList<Double>()); for (int j = 0; j < numberRules; j++) { * socialNetwork.get(i).add(0.0); * * } * * } */ for (int i = 0; i < numberRules; i++) { byte[] rulei = matrixRulesXExamples[i]; socialNetwork.add(new ArrayList<Double>()); // We calculate the denominator of the metric formula double denomi = 0; for (int k = 0; k < rulei.length; k++) { if (rulei[k] == 1) denomi += matrixFiringDegrees[i][k]; } for (int j = 0; j < numberRules; j++) { if (i == j) { socialNetwork.get(i).add(0.0); } else { double numij = 0; byte[] rulej = matrixRulesXExamples[j]; for (int k = 0; k < rulei.length; k++) { if (rulei[k] == 1) { if (rulej[k] == 1) { numij += Math.abs(matrixFiringDegrees[i][k] - matrixFiringDegrees[j][k]); } else { numij += matrixFiringDegrees[i][k]; } }// if }// for k socialNetwork.get(i).add(1 - (numij / denomi)); }// for j }// if i!=j }// for i } /* * private void generateDirectedMatrix2() { * * socialNetwork = new ArrayList<List<Double>>(numberRules); // List<Float> * totalFiringDegrees = new ArrayList<Float>(); * * // Create the identity matrix in result for (int i = 0; i < numberRules; * i++) { socialNetwork.add(new ArrayList<Double>()); for (int j = 0; j < * numberRules; j++) { socialNetwork.get(i).add(0.0); * * } * * } * * for (int i = 0; i < numberRules; i++) { * * for (int j = 0; j < listExamplesCoveredByRule.get(i).size(); j++) { int * examplei = listExamplesCoveredByRule.get(i).get(j); * * for (int k = 0; k < numberRules; k++) { * * for (int l = 0; l < listExamplesCoveredByRule.get(k).size(); l++) { int * examplek = listExamplesCoveredByRule.get(k).get(l); * * if (l == 0) { Double previous = socialNetwork.get(i).get(k); Double * currentValue = firingDegrees.get(i).get(j); socialNetwork.get(i) .set(k, * previous + currentValue); } if (examplei == examplek) { Double previous = * socialNetwork.get(i).get(k); Double currentValue = * Math.abs(firingDegrees.get(i) .get(j) - firingDegrees.get(k).get(l)); // * currentValue=1f; socialNetwork.get(i).set( k, previous - * firingDegrees.get(i).get(j) + currentValue); } } } } * * } * * for (int i = 0; i < numberRules; i++) { for (int j = 0; j < numberRules; * j++) { if (totalFiringDegrees.get(i) != 0 && totalFiringDegrees.get(j) != * 0 && i != j) { socialNetwork .get(i) .set(j, 1 - * (socialNetwork.get(i).get(j) / totalFiringDegrees .get(i))); * * } } } * * } */ public void calculateLift(String file) { try { // Read file 'file' and store its info in fileContent String fileContent = (new AdministrativeStaff()) .readFileAsString(file); // Split the entire file line by line String[] line = fileContent.split("[\\r\\n]+"); // Get the number of rules from the file numberRules = Integer.parseInt(line[3].split("[: ]+")[1]); // // // Obtain the information for the first rule, just to store // the min and max values of lift and support int j = 4; // Obtain the information from file // ruleSupport Double ruleSupport = Double.parseDouble(line[j + 1] .split("(=>)[ ]+")[1].split("[() ]+")[2]); // antecedentSupport Double antecedentSupport = Double.parseDouble(line[j + 2] .split("(=>)[ ]+")[1].split("[() ]+")[2]); // consequentSupport Double consequentSupport = Double.parseDouble(line[j + 3] .split("(=>)[ ]+")[1].split("[() ]+")[2]); // Stores the support of the rule support.add(ruleSupport); // confidence confidence.add(support.get(0) / antecedentSupport); // lift lift.add(confidence.get(0) / consequentSupport); // Store the min and max support with the first rule minSupport = ruleSupport; maxSupport = ruleSupport; // Store the min and max lift with the first rule minLift = lift.get(0); maxLift = lift.get(0); // Iterate among the rules to calculate confidence, support and lift for (int i = 1; i < numberRules; i += 1) { // Jumps over 4 lines every time j = 4 + i * 4; // Obtain the information from file // ruleSupport ruleSupport = Double .parseDouble(line[j + 1].split("(=>)[ ]+")[1] .split("[() ]+")[2]); // antecedentSupport antecedentSupport = Double.parseDouble(line[j + 2] .split("(=>)[ ]+")[1].split("[() ]+")[2]); // consequentSupport consequentSupport = Double.parseDouble(line[j + 3] .split("(=>)[ ]+")[1].split("[() ]+")[2]); // Stores the support of the rule support.add(ruleSupport); // confidence confidence.add(support.get(i) / antecedentSupport); // lift lift.add(confidence.get(i) / consequentSupport); if (minSupport > ruleSupport) minSupport = ruleSupport; if (maxSupport < ruleSupport) maxSupport = ruleSupport; if (minLift > lift.get(i)) minLift = lift.get(i); if (maxLift < lift.get(i)) maxLift = lift.get(i); } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void generateScienceMapFile(double MaxThr) { } @Override public String createNodeUncoveredExamples() { // TODO Auto-generated method stub String node; double coverage = (double) numberUncoveredExamples / this.numberExamples; DecimalFormat df = new AdministrativeStaff().format(); String nodeInfo = "UNCOVERED\\nEXAMPLES\\n(cov=" + df.format(coverage) + ")"; String nodeInfoToolTipText = "UNCOVERED EXAMPLES (cov=" + df.format(coverage) + "): "; for (int i = 0; i < uncoveredExamples.size(); i++) { nodeInfoToolTipText += uncoveredExamples.get(i) + ", "; } String nodeColor = "\"red\""; String fontColor = "black"; double nodeSize = 1 + 4 * coverage; // Set the font size float fontSize = 15 + 2 * ((int) nodeSize); node = "UNCOVERED [shape=circle,style=filled,height=" + df.format(nodeSize) + ",width=" + df.format(nodeSize) + ",fixedsize=true" + ",peripheries=0" + ",fillcolor=" + nodeColor + ",fontsize=" + fontSize + ",fontcolor=" + fontColor + ",label=\"" + nodeInfo + "\"" + ",tooltip=\"" + nodeInfoToolTipText + "\"];\n\t"; return node; // return ""; } @Override public boolean hasRuleUncoveredExamples() { // TODO Auto-generated method stub // System.out.println(ruleUncoveredExamples); examplesCoveredByASingleRule(); return ruleUncoveredExamples; } @Override public void printFingramsLegend() { try { DecimalFormat df = (new AdministrativeStaff()).format(); int numberConclusions = this.possibleLabelConclusions.size(); int elementsLegend = numberConclusions; if (this.hasRuleUncoveredExamples()) { elementsLegend++; } String headLegend = (new AdministrativeStaff()).headLegend( elementsLegend, "Output class rules"); PrintStream pslegend = new PrintStream(new FileOutputStream( this.fileLocation + ".legend.svg", false)); pslegend.print(headLegend); for (int n = 0; n < 3; n++) { String stroke = "black"; String color = "grey"; String label = ""; stroke = color; if (n == 0) { color = "black"; label = "The highest lift (" + df.format(maxLift) + ")"; } else if (n == 1) { color = "grey"; label = "Medium lift"; } else if (n == 2) { color = "white"; stroke = "black"; label = "The lowest lift (" + df.format(minLift) + ")"; } int id = n + 1; pslegend.println("<g id=\"node" + id + "\" class=\"node\"><title></title>"); int x = 125; int y = -405 + n * 55; pslegend.println("<ellipse fill=\"" + color + "\" stroke=\"" + stroke + "\" cx=\"" + x + "\" cy=\"" + y + "\" rx=\"25\" ry=\"25\"/>"); int dy = y + 5; pslegend.print("<text text-anchor=\"start\" x=\"170\" y=\"" + dy + "\" font-family=\"Times New Roman,serif\" font-size=\"18.00\">"); pslegend.println(label + "</text>"); pslegend.println("</g>"); } pslegend.println("</g>"); pslegend.println("</svg>"); pslegend.flush(); pslegend.close(); } catch (Exception e) { e.printStackTrace(); } } private void examplesCoveredByASingleRule() { int count = 0; for (int i = 0; i < numberExamples; i++) { // Iterate // over the // examples count = 0; for (int j = 0; j < matrixRulesXExamples.length; j++) { // Iterate // over // rules if ((byte) (matrixRulesXExamples[j][i]) == 1) { count++; } } if (count == 0) System.out.println("Example: " + i + " not covered by any rule"); } } }