apriori算法源码思想精简版(spmf-Java版)
//第一部分:导入一些包,定义一些变量,做一些准备工作。
//后面会用到这一个包里面的代码
//Eg: //这个Java文件会涉及到下面这三个Java文件
import DM.apriori.ArraysAlgos;
import DM.apriori.Itemset;
import DM.apriori.Itemsets;
import DM.apriori.MemoryLogger;
public class AlgoApriori
{
/*第二部分-------进行数据读取工作,顺便计算了size=1的support。根据输入文件IO路径, * 每一行按照“ ”分割,分割后存入数组中然后存入map中, * key是每一个项,value是key出现的次数,即支持度计数。这一部分获得size=1的项及其支持度,并把数据存入database。 另外顺便对某些变量进行了初始化 */
public Itemsets runAlgorithm(double minsup, String input, String output) throws IOException
{
Map<Integer, Integer> mapItemCount = new HashMap<Integer, Integer>();
while (((line = reader.readLine()) != null))
{
String[] lineSplited = line.split(" ");
for (int i=0; i< lineSplited.length; i++)
{
/* 第三部分:生成频繁1-项集。(当k=1时)比较第二部分中候选1项集中的sopport与minsupport的大小,判断是否频*对频繁1-项集排好
for(Entry<Integer, Integer> entry : mapItemCount.entrySet())
{
Collections.sort(frequent1, new Comparator<Integer>()
{
});
/*第四部分:如何由频繁k-1项集生成候选Ck项集分为2种情况。* 当k=2时,由频繁1-项集生成候选2-项集。这个情况比较简单
* 直接依次比较组合即可,源代码也是这样实现的,在生成候选集前,上一部分已经对候选集进行了排列
* 使候选集按照字典序列排列。
* 当k>2是,采用常规的方法,这个里面涉及判断子集的方法。原理:前k-1阶相等,但是第k阶不等
* 此时才能合并生成候选k-项集。(其实此时产生的集合是候选集的候选集)why?因为这个集合需要先判断其子集是否是频繁的,
* 从而去掉一部分子集不是频繁的集合,此时才是真正的候选集。
*/
if(k ==2)
{ //调用这个函数(在此文件后面)
candidatesK = generateCandidate2(frequent1);
}
else
{
// otherwise we use the regular way to generate candidates
//调用这个函数(也在此文件后面)而这个函数还会调用判断子集函数,此子集判断函数采用二分查找方法。
candidatesK = generateCandidateSizeK(level);
}
// 第五部分,扫描数据库,计算每个候选K项集的支持度
* // 对于某一个k阶候选项集,依次产生它的所有的k-1阶候选项集
//spfm使用了一个很让我佩服的策略是设置一个下标posRemoved,
//用该标志来指明应该被忽视的项,假设候选项candidate有三个元素{1 2 3}。
//则当posRemoved=0时,第一个元素1被忽略,即产生子集{2 3}。同理依次产生子集
*/
protected boolean allSubsetsOfSizeK_1AreFrequent(int[] candidate, List<Itemset> levelK_1) {
/*
* //samAs()是自定义的比较函数,比较k-1阶子集与middle所指的k-1阶频繁项集的大小
//若相等则返回为0,小于则返回1,大于则返回-1,下面的代码就是
//普通的折半查找算法,很容易理解,如果找到,就把found置true
*/