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]
其實還有兩個地方沒有改正,不過對于入門的同學應該可以看看,求指正批評!!