Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package opennlp.tools.fca; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.commons.collections.ListUtils; public class BasicLevelMetrics { ConceptLattice cl; ArrayList<ArrayList<Integer>> attributesExtent = null; ArrayList<ArrayList<Integer>> objectsIntent = null; ArrayList<Integer> attributes = null; double[][] objectsSimilarityJ = null; double[][] objectsSimilaritySMC = null; public BasicLevelMetrics(ConceptLattice cl) { this.cl = cl; this.attributesExtent = null; objectsSimilarityJ = new double[cl.objectCount][cl.objectCount]; objectsSimilaritySMC = new double[cl.objectCount][cl.objectCount]; } public void setUp() { attributesExtent = new ArrayList<ArrayList<Integer>>(); objectsIntent = new ArrayList<ArrayList<Integer>>(); attributes = new ArrayList<Integer>(); for (int i = 0; i < cl.attributeCount; i++) { attributesExtent.add((ArrayList<Integer>) cl.getAttributeExtByID(i)); attributes.add(i); } for (int i = 0; i < cl.objectCount; i++) { objectsIntent.add((ArrayList<Integer>) cl.getObjectIntByID(i)); } double[] buf = new double[2]; for (int i = 0; i < cl.objectCount; i++) { for (int j = i + 1; j < cl.objectCount; j++) { buf = simJ_SMC(objectsIntent.get(i), objectsIntent.get(j)); objectsSimilarityJ[i][j] = buf[0]; objectsSimilarityJ[j][i] = buf[0]; objectsSimilaritySMC[i][j] = buf[1]; objectsSimilaritySMC[j][i] = buf[1]; } objectsSimilarityJ[i][i] = 1; objectsSimilaritySMC[i][i] = 1; } //System.out.println("J"); //System.out.println(Arrays.deepToString(objectsSimilarityJ)); //System.out.println("SMC"); //System.out.println(Arrays.deepToString(objectsSimilaritySMC)); } //Utility functions for Similarity approach (S) public double simSMC(ArrayList<Integer> intent1, ArrayList<Integer> intent2) { int tp = (ListUtils.intersection(intent1, intent2)).size(); ArrayList<Integer> fnlst = new ArrayList<Integer>(); fnlst.addAll(this.attributes); fnlst.removeAll(ListUtils.union(intent1, intent2)); int fn = fnlst.size(); return (this.attributes.size() > 0) ? 1. * (tp + fn) / this.attributes.size() : 0; } public double simJ(ArrayList<Integer> intent1, ArrayList<Integer> intent2) { return 1. * (ListUtils.intersection(intent1, intent2)).size() / (ListUtils.union(intent1, intent2)).size(); } public double[] simJ_SMC(ArrayList<Integer> intent1, ArrayList<Integer> intent2) { double simJ = 0; double simSMC = 0; Set<Integer> intersection = new HashSet<Integer>(); intersection.addAll(intent1); intersection.retainAll(intent2); Set<Integer> union = new HashSet<Integer>(); union.addAll(intent1); union.addAll(intent2); int fn = 0; Set<Integer> unionOut = new HashSet<Integer>(); unionOut.addAll(this.attributes); unionOut.removeAll(union); simSMC = (this.attributes.size() > 0) ? 1. * (intersection.size() + unionOut.size()) / this.attributes.size() : 0; simJ = (union.size() > 0) ? 1. * intersection.size() / union.size() : 0; return new double[] { simJ, simSMC }; } public double avgCohSMC(FormalConcept c) { double sum = 0; if (c.extent.size() == 1) return 1.;//c.intent.size(); if (c.extent.size() == 0) return 0.; else { for (Integer i : c.extent) { for (Integer j : c.extent) { if (i < j) sum += objectsSimilaritySMC[i][j]; } } return (c.extent.size() > 1) ? 2. * sum / c.extent.size() / (c.extent.size() - 1) : 0;// 2, } } public double avgCohJ(FormalConcept c) { double sum = 0; if (c.extent.size() == 1) return 1.;//c.intent.size(); if (c.extent.size() == 0) return 0.; else { for (Integer i : c.extent) { for (Integer j : c.extent) { if (i < j) { sum += objectsSimilarityJ[i][j]; } } } return (c.extent.size() > 1) ? 2. * sum / c.extent.size() / (c.extent.size() - 1) : 0; } } public double minCohJ(FormalConcept c) { double min = Integer.MAX_VALUE, val = 0; for (Integer i : c.extent) { for (Integer j : c.extent) { val = objectsSimilarityJ[i][j]; if (val < min) min = val; } } return (min < Integer.MAX_VALUE) ? min : 0; } public double minCohSMC(FormalConcept c) { double min = Integer.MAX_VALUE, val = 0; for (Integer i : c.extent) { for (Integer j : c.extent) { val = objectsSimilaritySMC[i][j]; if (val < min) min = val; } } return (min < Integer.MAX_VALUE) ? min : 0; } public double upperCohAvgByAvgJ(FormalConcept c, float tetta) { //average alpha with average cohesion J double sum = 0; Set<Integer> upperNeighbors = c.parents; int rightNeighborsNumber = 0; float truthDegree = 0; for (Integer i : upperNeighbors) { if (c.cohAvgJ > cl.conceptList.get(i).cohAvgJ) { rightNeighborsNumber++; sum += 1. * cl.conceptList.get(i).cohAvgJ / c.cohAvgJ; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; //truthDegree = (float) Math.min(1.0, truthDegree); return (1 - sum / rightNeighborsNumber) * truthDegree; } } public double upperCohAvgByMinJ(FormalConcept c, float tetta) { //average alpha with min cohesion J double sum = 0; Set<Integer> upperNeighbors = c.parents; int rightNeighborsNumber = 0; float truthDegree = 0; for (Integer i : upperNeighbors) { if (c.cohMinJ > cl.conceptList.get(i).cohMinJ) { rightNeighborsNumber++; sum += 1. * cl.conceptList.get(i).cohMinJ / c.cohMinJ; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (1 - sum / rightNeighborsNumber) * truthDegree; } } public double upperCohMinByAvgJ(FormalConcept c, float tetta) { //min alpha whth average cohesion J double max = Integer.MIN_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> upperNeighbors = c.parents; for (Integer i : upperNeighbors) { if (c.cohAvgJ > cl.conceptList.get(i).cohAvgJ) { rightNeighborsNumber++; val = 1. * cl.conceptList.get(i).cohAvgJ / c.cohAvgJ; if (val > max) max = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (1 - max) * truthDegree; } } public double upperCohMinByMinJ(FormalConcept c, float tetta) { //min alpha whth average cohesion J double max = Integer.MIN_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> upperNeighbors = c.parents; for (Integer i : upperNeighbors) { if (c.cohMinJ > cl.conceptList.get(i).cohMinJ) { rightNeighborsNumber++; val = 1. * cl.conceptList.get(i).cohMinJ / c.cohMinJ; if (val > max) max = val; } } if (rightNeighborsNumber == 0) return 0; else { //truthDegree = rightNeighborsNumber/tetta/upperNeighbors.size(); truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (1 - max) * truthDegree; } } public double upperCohAvgByAvgSMC(FormalConcept c, float tetta) { //average alpha with average cohesion SMC double sum = 0; Set<Integer> upperNeighbors = c.parents; int rightNeighborsNumber = 0; float truthDegree = 0; for (Integer i : upperNeighbors) { if (c.cohAvgSMC > cl.conceptList.get(i).cohAvgSMC) { rightNeighborsNumber++; sum += 1. * cl.conceptList.get(i).cohAvgSMC / c.cohAvgSMC; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; return (1 - sum / rightNeighborsNumber) * truthDegree; } } public double upperCohAvgByMinSMC(FormalConcept c, float tetta) { //average alpha with min cohesion SMC double sum = 0; Set<Integer> upperNeighbors = c.parents; int rightNeighborsNumber = 0; float truthDegree = 0; for (Integer i : upperNeighbors) { if (c.cohMinSMC > cl.conceptList.get(i).cohMinSMC) { rightNeighborsNumber++; sum += 1. * cl.conceptList.get(i).cohMinSMC / c.cohMinSMC; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; return (1 - sum / rightNeighborsNumber) * truthDegree; } } public double upperCohMinByAvgSMC(FormalConcept c, float tetta) { //min alpha whth average cohesion J double max = Integer.MIN_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> upperNeighbors = c.parents; for (Integer i : upperNeighbors) { if (c.cohAvgSMC > cl.conceptList.get(i).cohAvgSMC) { rightNeighborsNumber++; val = 1. * cl.conceptList.get(i).cohAvgSMC / c.cohAvgSMC; if (val > max) max = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (1 - max) * truthDegree; } } public double upperCohMinByMinSMC(FormalConcept c, float tetta) { //min alpha whth average cohesion J double max = Integer.MIN_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> upperNeighbors = c.parents; for (Integer i : upperNeighbors) { if (c.cohMinSMC > cl.conceptList.get(i).cohMinSMC) { rightNeighborsNumber++; val = 1. * cl.conceptList.get(i).cohMinSMC / c.cohMinSMC; if (val > max) max = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / upperNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (1 - max) * truthDegree; } } public double lowerCohAvgByAvgJ(FormalConcept c, float tetta) { double sum = 0; Set<Integer> lowerNeighbors = c.childs; int rightNeighborsNumber = 0; float truthDegree = 0; for (Integer i : lowerNeighbors) { if (c.cohAvgJ < cl.conceptList.get(i).cohAvgJ) { rightNeighborsNumber++; sum += 1. * c.cohAvgJ / cl.conceptList.get(i).cohAvgJ; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (sum / rightNeighborsNumber) * truthDegree; } } public double lowerCohAvgByMinJ(FormalConcept c, float tetta) { double sum = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohMinJ < cl.conceptList.get(i).cohMinJ) { rightNeighborsNumber++; sum += 1. * c.cohMinJ / cl.conceptList.get(i).cohMinJ; } } if (rightNeighborsNumber == 0) return 0; else { //truthDegree = rightNeighborsNumber/tetta/lowerNeighbors.size(); truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (sum / rightNeighborsNumber) * truthDegree; } } public double lowerCohMinByAvgJ(FormalConcept c, float tetta) { double min = Integer.MAX_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohAvgJ < cl.conceptList.get(i).cohAvgJ) { rightNeighborsNumber++; val = 1. * c.cohAvgJ / cl.conceptList.get(i).cohAvgJ; if (val < min) min = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (min) * truthDegree; } } public double lowerCohMinByMinJ(FormalConcept c, float tetta) { double min = Integer.MAX_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohMinJ < cl.conceptList.get(i).cohMinJ) { rightNeighborsNumber++; val = 1. * c.cohMinJ / cl.conceptList.get(i).cohMinJ; if (val < min) min = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (min) * truthDegree; } } public double lowerCohAvgByAvgSMC(FormalConcept c, float tetta) { double sum = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohAvgSMC < cl.conceptList.get(i).cohAvgSMC) { rightNeighborsNumber++; sum += 1. * c.cohAvgSMC / cl.conceptList.get(i).cohAvgSMC; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (sum / rightNeighborsNumber) * truthDegree; } } public double lowerCohAvgByMinSMC(FormalConcept c, float tetta) { double sum = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohMinSMC < cl.conceptList.get(i).cohMinSMC) { rightNeighborsNumber++; sum += 1. * c.cohMinSMC / cl.conceptList.get(i).cohMinSMC; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (sum / rightNeighborsNumber) * truthDegree; } } public double lowerCohMinByAvgSMC(FormalConcept c, float tetta) { double min = Integer.MAX_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohAvgSMC <= cl.conceptList.get(i).cohAvgSMC) { rightNeighborsNumber++; val = 1. * c.cohAvgSMC / cl.conceptList.get(i).cohAvgSMC; if (val < min) min = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; truthDegree = (float) Math.min(1.0, truthDegree); return (min) * truthDegree; } } public double lowerCohMinByMinSMC(FormalConcept c, float tetta) { double min = Integer.MAX_VALUE, val = 0; int rightNeighborsNumber = 0; float truthDegree = 0; Set<Integer> lowerNeighbors = c.childs; for (Integer i : lowerNeighbors) { if (c.cohMinSMC < cl.conceptList.get(i).cohMinSMC) { rightNeighborsNumber++; val = 1. * c.cohMinSMC / cl.conceptList.get(i).cohMinSMC; if (val < min) min = val; } } if (rightNeighborsNumber == 0) return 0; else { truthDegree = (1. * rightNeighborsNumber / lowerNeighbors.size() >= tetta) ? 1 : 0; return (min) * truthDegree; } } //Similarity approach (S) //group of metrics: // SMC avg_avg, avg_min, min_avg // J avg_avg, avg_min, min_avg public void similarityGoguenNorm() { // // double[] buf = new double[2]; if (objectsSimilaritySMC == null) this.setUp(); //upper neighbors - alpha2 //lower neighbors - alpha3 for (FormalConcept c : cl.conceptList) { c.cohAvgJ = avgCohJ(c); c.cohMinJ = minCohJ(c); c.cohAvgSMC = avgCohSMC(c); c.cohMinSMC = minCohSMC(c); } for (FormalConcept c : cl.conceptList) { float tetta = 1; c.blS_Jaa = (c.cohAvgJ != 0) ? c.cohAvgJ * upperCohAvgByAvgJ(c, tetta) * lowerCohAvgByAvgJ(c, tetta) : 0; c.blS_Jma = (c.cohMinJ != 0) ? c.cohMinJ * upperCohAvgByMinJ(c, tetta) * lowerCohAvgByMinJ(c, tetta) : 0; c.blS_Jam = (c.cohAvgJ != 0) ? c.cohAvgJ * upperCohMinByAvgJ(c, tetta) * lowerCohMinByAvgJ(c, tetta) : 0; c.blS_Jmm = (c.cohMinJ != 0) ? c.cohMinJ * upperCohMinByMinJ(c, tetta) * lowerCohMinByMinJ(c, tetta) : 0; c.blS_SMCaa = (c.cohAvgSMC != 0) ? c.cohAvgSMC * upperCohAvgByAvgSMC(c, tetta) * lowerCohAvgByAvgSMC(c, tetta) : 0; c.blS_SMCma = (c.cohMinSMC != 0) ? c.cohMinSMC * upperCohAvgByMinSMC(c, tetta) * lowerCohAvgByMinSMC(c, tetta) : 0; c.blS_SMCam = (c.cohAvgSMC != 0) ? c.cohAvgSMC * upperCohMinByAvgSMC(c, tetta) * lowerCohMinByAvgSMC(c, tetta) : 0; c.blS_SMCmm = (c.cohMinSMC != 0) ? c.cohMinSMC * upperCohMinByMinSMC(c, tetta) * lowerCohMinByMinSMC(c, tetta) : 0; } } //Cue validity approach (CV) public void cueValidity() { if (attributesExtent == null) this.setUp(); ArrayList<Integer> attrExtent; Set<Integer> intersection; double sum = 0; for (FormalConcept c : cl.conceptList) { sum = 0; for (Integer i : c.intent) { intersection = new HashSet<Integer>(); intersection.addAll(c.extent); attrExtent = attributesExtent.get(i); intersection.retainAll(attrExtent); sum += (double) intersection.size() * 1. / attrExtent.size(); } c.blCV = Double.isNaN(sum) ? 0 : sum; } } //Category feature collocation approach public void categoryFeatureCollocation() { if (attributesExtent == null) this.setUp(); ArrayList<Integer> attrExtent; Set<Integer> intersection; double sum = 0; int latticeSize = cl.conceptList.size(); for (FormalConcept c : cl.conceptList) { sum = 0; for (int i = 0; i < cl.attributeCount; i++) { intersection = new HashSet<Integer>(); intersection.addAll(c.extent); attrExtent = attributesExtent.get(i); intersection.retainAll(attrExtent); sum += (double) intersection.size() * 1. / attrExtent.size() * intersection.size() / c.extent.size(); } c.blCFC = Double.isNaN(sum) ? 0 : sum; } } //Category utility approach public void categoryUtility() { if (attributesExtent == null) this.setUp(); ArrayList<Integer> attrExtent; Set<Integer> intersection; double sum = 0; int attrSize = cl.objectCount; int cExtentSize = 0; for (FormalConcept c : cl.conceptList) { sum = 0; for (int i = 0; i < cl.attributeCount; i++) { intersection = new HashSet<Integer>(); intersection.addAll(c.extent); cExtentSize = c.extent.size(); attrExtent = attributesExtent.get(i); intersection.retainAll(attrExtent); sum += (double) Math.pow(intersection.size() * 1. / cExtentSize, 2) - Math.pow(1. * attrExtent.size() / attrSize, 2); } c.blCU = Double.isNaN(1. * cExtentSize / attrSize * sum) ? 0 : 1. * cExtentSize / attrSize * sum; } } //Predictability approach (P) public void predictability() { if (attributesExtent == null) this.setUp(); ArrayList<Integer> attributes = new ArrayList<Integer>(); ArrayList<Integer> outOfIntent = new ArrayList<Integer>(); Set<Integer> intersection; ArrayList<Integer> attrExtent; double sum, term; for (int i = 0; i < cl.attributeCount; i++) { attributes.add(i); } for (FormalConcept c : cl.conceptList) { sum = 0; outOfIntent = new ArrayList<Integer>(); outOfIntent.addAll(attributes); outOfIntent.removeAll(c.intent); for (Integer y : outOfIntent) { intersection = new HashSet<Integer>(); intersection.addAll(c.extent); attrExtent = attributesExtent.get(y); intersection.retainAll(attrExtent); term = 1. * intersection.size() / c.extent.size(); if (term > 0) { sum -= term * Math.log(term); } } c.blP = Double.isNaN(1 - sum / outOfIntent.size()) ? 0 : 1 - sum / outOfIntent.size(); } } }