package apriori;
import java.util.*;
import java.io.*;
public class aprioti {
public static int k_item=3;//产生的频繁项集数,但其实在我这里不是真正的项集数,只是迭代的次数,在[beer,ham][cola,diaper]这种情况下会产生频繁4项集!!
//只要修改一下就可以,但是我觉得这样也好所以就没有修改
public static double min_support_count =2;//最小支持度计数值
public static string path="f:\\firstgit\\apriori\\";
public static list<itemset>allitemset = new arraylist<itemset>();
public static itemset originalitem = new itemset();
public static void main(string [] args)
{
aprioriprocess();
}
public static void aprioriprocess()
readitemfromtext(path,originalitem);//读取硬盘上的数据集
itemset firstitemset =new itemset();
gen_first_item_set(firstitemset);//首先生成频繁1项集
int k =k_item;
itemset forworditemset =firstitemset;
delete_blew_support_count(forworditemset);//去除低于最小支持度计数的项集
allitemset.add(firstitemset);//将所有的频繁项集保存起来
while(k--!=0)
{
itemset backworditemset =new itemset();
apriori_gen(forworditemset,backworditemset);//根据频繁k-1项集生成频繁k项集
delete_blew_support_count(backworditemset);//去除小于支持度计数的项集
allitemset.add(backworditemset);
forworditemset=backworditemset;//将指针指向频繁k-1项集
}
printresult();//输出结果
public static void printresult()
for(int i=0;i<allitemset.size();i++)
itemset itemset = allitemset.get(i);
for(treeset<string> everyitem : itemset.itemset)
{
system.out.println(everyitem.tostring());
}
/*
* 不可以一边遍历一边删除集合中的数据,这样会让你的集合遍历不完整或者越界!
*/
public static void delete_blew_support_count(itemset itemset)
/*
* 在这里可以用迭代器iterator也可以用size()的形式来,
* 其中用iterator会遍历的时候不可以删除元素
* 用size可以删除元素,但是最后的n(n是中途被删除的个数)个元素就没有遍历到!!!!
*/
arraylist<integer> deletesetnum= new arraylist<integer>();
for(int i=0;i<itemset.itemset.size();i++)
double suppoutcount=0;
treeset<string> item = itemset.itemset.get(i);
boolean ispinfan=false;
for(treeset<string> oriitem : originalitem.itemset)
if(contain(oriitem,item))
suppoutcount++;
if(suppoutcount>=min_support_count)
{
ispinfan=true;
break;
}
if(!ispinfan)
deletesetnum.add(i);
for(int j=deletesetnum.size()-1;j>=0;j--)
//system.out.println(deletesetnum.get(j));
itemset.itemset.remove((int)deletesetnum.get(j));
* 下面这种做法由于remove
* 的时候会改变集合的大小,所以不可以从头开始remove只可以从后面remove
* 这样就保证不会越界
// for(int i :deletesetnum)
// {
// system.out.println(i);
// itemset.itemset.remove(i);
// }
//产生1项集
public static void gen_first_item_set(itemset firstitemset)
treeset<string> itemset = new treeset<string>();
for(treeset<string> per_ori_item : originalitem.itemset)
for(string item : per_ori_item)
itemset.add(item);
for(string word : itemset)
treeset<string> everyitemset = new treeset<string>();
everyitemset.add(word);
firstitemset.itemset.add(everyitemset);
* 根据k-1项频繁产生频繁k项项集
public static void apriori_gen(itemset one_item,itemset second_item)
for(int i=0;i<one_item.itemset.size();i++)
for(int j=i+1;j<one_item.itemset.size();j++)
treeset<string> newitem=new treeset<string>();
for(string peritem: one_item.itemset.get(i))
newitem.add(peritem);
for(string peritem: one_item.itemset.get(j))
//如果没有非频繁k-1项集,加入k项集
if(!has_infrequent_subset(newitem,one_item))
if(!find_in_already_set(newitem,second_item))//并且项集没有在之前出现
second_item.itemset.add(newitem);
public static boolean find_in_already_set(treeset<string> newitem,itemset second_item)
for(int i=0;i<second_item.itemset.size();i++)
if(newitem.equals(second_item.itemset.get(i)))//记住,treeset也可以用equals,这个函数真是好用,不过有时候效率低
return true;
return false;
public static boolean has_infrequent_subset(treeset<string> newitem,itemset one_item1)//这里写错了!
for(treeset<string> k_1_item : one_item1.itemset)
if(!contain(newitem,k_1_item))
return false;
return true;
public static boolean contain(treeset<string> big,treeset<string>small)
for(string smallword : small)
if(!big.contains(smallword))
public static void readitemfromtext(string path,itemset originalitem)
file file =new file(path);
if(file.isdirectory())
string [] filelist = file.list();
for(int i =0;i<filelist.length;i++)
try {
bufferedreader br = new bufferedreader(new filereader(new file(path+filelist[i])));
string line =null;
while((line = br.readline())!=null)
{
string [] lineword = line.split("[^\\s]+");
treeset<string> itemset = new treeset<string>();
for(string word : lineword)
{
itemset.add(word);
}
originalitem.itemset.add(itemset);
}
} catch (exception e) {
e.printstacktrace();
}
上面代码中用到的itemset,由于不想老是写那么长的代码,所以就将其封装为一个类
public class itemset {
public arraylist<treeset<string>> itemset = new arraylist<treeset<string>>();
输入的数据集如下:
cola egg ham
cola diaper beer
cola diaper beer ham
diaper beer
输出结果如下:
[beer]
[cola]
[diaper]
[ham]
[beer, cola]
[beer, diaper]
[cola, diaper]
[cola, ham]
[beer, cola, diaper]
其实还有两个地方没有改正,不过对于入门的同学应该可以看看,求指正批评!!