Apriori算法实现(二)
2014-11-24 08:14:21
·
作者:
·
浏览: 1
tem);// 该候选去掉一项后变为k-1项集 if(!freqMItemSet.contains(tempSet))// 判断k-1项集是否是频繁项集 return true; tempSet.add(item);// 恢复 } return false; } /** * 根据一个频繁k-项集的元素(集合),获取到频繁k-项集的从该元素开始的迭代器实例 * @param itemSet * @param freqKItemSet 频繁k-项集 * @return */ private Iterator
> getIterator(Set
itemSet, Set
> freqKItemSet) { Iterator
> it = freqKItemSet.iterator(); while(it.hasNext()) { if(itemSet.equals(it.next())) { break; } } return it; } /** * 根据频繁(k-1)-项集,调用aprioriGen方法,计算频繁k-项集 * * @param k * @param freqMItemSet 频繁(k-1)-项集 * @return */ public Map
, Float> getFreqKItemSet(int k, Set
> freqMItemSet) { Map
, Integer> candFreqKItemSetMap = new HashMap
, Integer>(); // 调用aprioriGen方法,得到候选频繁k-项集 Set
> candFreqKItemSet = this.aprioriGen(k-1, freqMItemSet); // 扫描事务数据库 Iterator
>> it = txDatabase.entrySet().iterator(); // 统计支持数 while(it.hasNext()) { Map.Entry
> entry = it.next(); Iterator
> kit = candFreqKItemSet.iterator(); while(kit.hasNext()) { Set
kSet = kit.next(); Set
set = new HashSet
(); set.addAll(kSet); set.removeAll(entry.getValue()); // 候选频繁k-项集与事务数据库中元素做差运算 if(set.isEmpty()) { // 如果拷贝set为空,支持数加1 if(candFreqKItemSetMap.get(kSet) == null) { Integer value = 1; candFreqKItemSetMap.put(kSet, value); } else { Integer value = 1+candFreqKItemSetMap.get(kSet); candFreqKItemSetMap.put(kSet, value); } } } } // 计算支持度,生成频繁k-项集,并返回 return support(candFreqKItemSetMap); } /** * 根据候选频繁k-项集,得到频繁k-项集 * * @param candFreqKItemSetMap 候选k项集(包含支持计数) * @return freqKItemSetMap 频繁k项集及其支持度(比例) */ public Map
, Float> support(Map
, Integer> candFreqKItemSetMap) { Map
, Float> freqKItemSetMap = new HashMap
, Float>(); Iterator
, Integer>> it = candFreqKItemSetMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry
, Integer> entry = it.next(); // 计算支持度 Float supportRate = new Float(entry.getValue().toString())/new Float(txDatabaseCount); if(supportRate
> freqKItemSet = this.getFreq1ItemSet().keySet(); freqItemSet.put(1, freqKItemSet); // 计算频繁k-项集(k>
1) int k = 2; while(true) { Map
, Float> freqKItemSetMap = this.getFreqKItemSet(k, freqKItemSet); if(!freqKItemSetMap.isEmpty()) { this.freqItemSet.put(k, freqKItemSetMap.keySet()); freqKItemSet = freqKItemSetMap.keySet(); } else { break; } k++; } } /** *
挖掘频繁关联规则 *
首先挖掘出全部的频繁项集,在此基础上挖掘频繁关联规则 */ public void mineAssociationRules() { freqItemSet.remove(1); // 删除频繁1-项集 Iterator
>>> it = freqItemSet.entrySet().iterator(); while(it.hasNext()) { Map.Entry
>> entry = it.next(); for(Set
itemSet : entry.getValue()) { // 对每个频繁项集进行关联规则的挖掘 mine(itemSet); } } } /** * 对从频繁项集集合freqItemSet中每迭代出一个频繁项集元素,执行一次关联规则的挖掘 * @param itemSet 频繁项集集合freqItemSet中的一个频繁项集元素 */ public void mine(Set
itemSet) { int n = itemSet.size()/2; // 根据集合的对称性,只需要得到一半的真子集 for(int i=1; i<=n; i++) { // 得到频繁项集元素itemSet的作为条件的真子集集合 Set
> properSubset = ProperSubsetCombination.getProperSubset(i, itemSet); // 对条件的真子集集合中的每个条件项集,获取到对应的结论项集,从而进一步挖掘频繁关联规则 for(Set
conditionSet : properSubset) { Set
conclusionSet = new HashSet
(); conclusionSet.addAll(itemSet); conclusionSet.removeAll(conditionSet); // 删除条件中存在的频繁项 confide(conditionSet, conclusionSet); // 调用计算置信度的方法,并且挖掘出频繁关联规则 } } } /** * 对得到的一个条件项集和对应的结论项集,计算该关联规则的支持计数,从而根据置信度判断是否是频繁关联规则 * @param conditionSet 条件频繁项集 * @param conclusionSet 结论频繁项集 */ public void confide(Set
conditionSet, Set
conclusionSet) { // 扫描事务数据库