1. 程式人生 > >Apriori演算法詳解之【二、虛擬碼和例子】

Apriori演算法詳解之【二、虛擬碼和例子】

上一篇文章中對Apriori演算法進行了簡單的描述(http://blog.csdn.net/lizhengnanhua/article/details/9061755),現在用虛擬碼實現,及對經典例子進行描述(紅蘭PPT上之摘抄)。

一、Apriori演算法虛擬碼實現:

虛擬碼描述:
 // 找出頻繁 1 項集
     L1 =find_frequent_1-itemsets(D); 
     For(k=2;Lk-1 !=null;k++){
// 產生候選,並剪枝
        Ck =apriori_gen(Lk-1 ); 
// 掃描 D 進行候選計數
        For each 事務t  in D{ 
            Ct =subset(Ck,t); // 得到 t 的子集
            For each 候選 c 屬於 Ct
                c.count++;
        }
		//返回候選項集中不小於最小支援度的項集
        Lk ={c 屬於 Ck | c.count>=min_sup}
}
Return L= 所有的頻繁集;
第一步:連線(join)
Procedure apriori_gen (Lk-1 :frequent(k-1)-itemsets)
      For each 項集 l1 屬於 Lk-1
         For each 項集 l2 屬於 Lk-1
            If( (l1 [1]=l2 [1])&&( l1 [2]=l2 [2])&& ……&& (l1 [k-2]=l2 [k-2])&&(l1 [k-1]<l2 [k-1]) ) 
then{
                    c = l1 連線 l2    // 連線步:產生候選
				  //若k-1項集中已經存在子集c則進行剪枝
                   if has_infrequent_subset(c, Lk-1 ) then
                       delete c; // 剪枝步:刪除非頻繁候選
                   else add c to Ck;
                   }
          Return Ck;
第二步:剪枝(prune) 
 Procedure has_infrequent_sub (c:candidate k-itemset; Lk-1 :frequent(k-1)-itemsets)
         For each (k-1)-subset s of c
            If s 不屬於 Lk-1 then
               Return true;
        Return false;
二Apriori演算法例子:

三、總結:

  ①Apriori演算法的缺點:(1)由頻繁k-1項集進行自連線生成的候選頻繁k項集數量巨大。(2)在驗證候選頻繁k項集的時候需要對整個資料庫進行掃描,非常耗時。

  ②網上提到的頻集演算法的幾種優化方法:1. 基於劃分的方法。2. 基於hash的方法。3. 基於取樣的方法。4. 減少交易的個數。

   我重點看了“基於劃分的方法”改進演算法,現在簡單介紹一下實現思想:

基於劃分(partition)的演算法,這個演算法先把資料庫從邏輯上分成幾個互不相交的塊,每次單獨考慮一個分塊並 對它生成所有的頻集,然後把產生的頻集合並,用來生成所有可能的頻集,最後計算這些項集的支援度。

其中,partition演算法要注意的是分片的大小選取,要保證每個分片可以被放入到記憶體。當每個分片產生頻集後,再合併產生產生全域性的候選k-項集。若在多個處理器分片,可以通過處理器之間共享一個雜湊樹來產生頻集。


   看這個圖基本再對照虛擬碼,基本就可以看懂了~簡單明瞭。