/** * Try to expand a rule by right expansion only. * * @param ruleG the rule */ private void expandR(RuleG ruleG) { // map to record the potential item to expand the right side of the rule // Key: item Value: bitset indicating the IDs of the transaction containing the item // from the transactions containing the rule. Map<Integer, BitSet> mapCountRight = new HashMap<Integer, BitSet>(); // for each transaction containing the rule for (int tid = ruleG.common.nextSetBit(0); tid >= 0; tid = ruleG.common.nextSetBit(tid + 1)) { // iterate over the items in this transaction Iterator<Integer> iter = database.getTransactions().get(tid).getItems().iterator(); while (iter.hasNext()) { Integer item = iter.next(); // if that item is not frequent, then remove it from the transaction if (tableItemCount[item] < minsuppRelative) { iter.remove(); continue; } // If the item is smaller than the largest item in the right side // of the rule, we can stop this loop because items // are sorted in lexicographical order. if (item < ruleG.maxRight) { break; } // if the item is larger than the maximum item in the right side // and is not contained in the left side of the rule if (item > ruleG.maxRight && !ArraysAlgos.containsLEX(ruleG.getItemset1(), item, ruleG.maxLeft)) { // update the tidset of the item BitSet tidsItem = mapCountRight.get(item); if (tidsItem == null) { tidsItem = new BitSet(); mapCountRight.put(item, tidsItem); } tidsItem.set(tid); } } } // for each item c found in the previous step, we create a rule // I ==> J U {c} if the support is enough for (Entry<Integer, BitSet> entry : mapCountRight.entrySet()) { BitSet tidsRule = entry.getValue(); int ruleSupport = tidsRule.cardinality(); // if the support is enough if (ruleSupport >= minsuppRelative) { Integer itemC = entry.getKey(); // create new right part of rule Integer[] newRightItemset = new Integer[ruleG.getItemset2().length + 1]; System.arraycopy(ruleG.getItemset2(), 0, newRightItemset, 0, ruleG.getItemset2().length); newRightItemset[ruleG.getItemset2().length] = itemC; // recompute maxRight int maxRight = itemC >= ruleG.maxRight ? itemC : ruleG.maxRight; // calculate confidence double confidence = ((double) ruleSupport) / ruleG.tids1.cardinality(); // create the rule RuleG candidate = new RuleG( ruleG.getItemset1(), newRightItemset, ruleSupport, ruleG.tids1, tidsRule, ruleG.maxLeft, maxRight); // if the confidence is enough if (confidence >= minConfidence) { // save the rule to the current top-k rules save(candidate, ruleSupport); } // register the rule as a candidate for future expansion(s) registerAsCandidate(false, candidate); } } }
/** * Try to expand a rule by left and right expansions. * * @param ruleG the rule */ private void expandLR(RuleG ruleG) { // Maps to record the potential item to expand the left/right sides of the rule // Key: item Value: bitset indicating the IDs of the transaction containing the item // from the transactions containing the rule. Map<Integer, BitSet> mapCountLeft = new HashMap<Integer, BitSet>(); Map<Integer, BitSet> mapCountRight = new HashMap<Integer, BitSet>(); for (int tid = ruleG.common.nextSetBit(0); tid >= 0; tid = ruleG.common.nextSetBit(tid + 1)) { Iterator<Integer> iter = database.getTransactions().get(tid).getItems().iterator(); while (iter.hasNext()) { Integer item = iter.next(); // CAN DO THIS BECAUSE TRANSACTIONS ARE SORTED BY DESCENDING // ITEM IDS (see Database.Java) if (item < ruleG.maxLeft && item < ruleG.maxRight) { // break; } if (tableItemCount[item] < minsuppRelative) { iter.remove(); continue; } if (item > ruleG.maxLeft && !ArraysAlgos.containsLEX(ruleG.getItemset2(), item, ruleG.maxRight)) { BitSet tidsItem = mapCountLeft.get(item); if (tidsItem == null) { tidsItem = new BitSet(); mapCountLeft.put(item, tidsItem); } tidsItem.set(tid); } if (item > ruleG.maxRight && !ArraysAlgos.containsLEX(ruleG.getItemset1(), item, ruleG.maxLeft)) { BitSet tidsItem = mapCountRight.get(item); if (tidsItem == null) { tidsItem = new BitSet(); mapCountRight.put(item, tidsItem); } tidsItem.set(tid); } } } // for each item c found in the previous step, we create a rule // I ==> J U {c} if the support is enough for (Entry<Integer, BitSet> entry : mapCountRight.entrySet()) { BitSet tidsRule = entry.getValue(); int ruleSupport = tidsRule.cardinality(); // if the support is enough if (ruleSupport >= minsuppRelative) { Integer itemC = entry.getKey(); // create new right part of rule Integer[] newRightItemset = new Integer[ruleG.getItemset2().length + 1]; System.arraycopy(ruleG.getItemset2(), 0, newRightItemset, 0, ruleG.getItemset2().length); newRightItemset[ruleG.getItemset2().length] = itemC; // recompute maxRight int maxRight = (itemC >= ruleG.maxRight) ? itemC : ruleG.maxRight; // calculate the confidence of the rule double confidence = ((double) ruleSupport) / ruleG.tids1.cardinality(); // create the rule RuleG candidate = new RuleG( ruleG.getItemset1(), newRightItemset, ruleSupport, ruleG.tids1, tidsRule, ruleG.maxLeft, maxRight); // if the confidence is enough if (confidence >= minConfidence) { // save the rule in current top-k rules save(candidate, ruleSupport); } // register the rule as a candidate for future expansion registerAsCandidate(false, candidate); } } // for each item c found in the previous step, we create a rule // I U {c} ==> J if the support is enough for (Entry<Integer, BitSet> entry : mapCountLeft.entrySet()) { BitSet tidsRule = entry.getValue(); int ruleSupport = tidsRule.cardinality(); // if the support is enough if (ruleSupport >= minsuppRelative) { Integer itemC = entry.getKey(); // The tidset of the left itemset is calculated BitSet tidsLeft = (BitSet) ruleG.tids1.clone(); tidsLeft.and(tableItemTids[itemC]); // create new left part of rule Integer[] newLeftItemset = new Integer[ruleG.getItemset1().length + 1]; System.arraycopy(ruleG.getItemset1(), 0, newLeftItemset, 0, ruleG.getItemset1().length); newLeftItemset[ruleG.getItemset1().length] = itemC; // recompute maxLeft int maxLeft = itemC >= ruleG.maxLeft ? itemC : ruleG.maxLeft; // calculate the confidence of the rule double confidence = ((double) ruleSupport) / tidsLeft.cardinality(); // create the rule RuleG candidate = new RuleG( newLeftItemset, ruleG.getItemset2(), ruleSupport, tidsLeft, tidsRule, maxLeft, ruleG.maxRight); // if the confidence is high enough if (confidence >= minConfidence) { // save the rule to the top-k rules save(candidate, ruleSupport); } // register the rule as a candidate for further expansions registerAsCandidate(true, candidate); } } }