數據挖掘apriori算法Java代碼實現
- 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))
- {
- newItem.add(peritem);
- }
- //如果沒有非頻繁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))
- return false;
- }
- return true;
- }
- 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,由於不想老是寫那麼長的代碼,所以就將其封裝為一個類
- package apriori;
- import java.util.*;
- 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]
其實還有兩個地方沒有改正,不過對於入門的同學應該可以看看,求指正批評!!
最後更新:2017-04-03 12:54:04