Apriori演算法的虛擬碼及執行個體:
<span style="font-size:18px;">虛擬碼描述: // 找出頻繁 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; </span> Apriori演算法的例子:
總結:
①Apriori演算法的缺點:(1)由頻繁k-1項集進行自串連產生的候選頻繁k項集數量巨大。(2)在驗證候選頻繁k項集的時候需要對整個資料庫進行掃描,非常耗時。
②網上提到的頻集演算法的幾種最佳化方法:1. 基於劃分的方法。2. 基於hash的方法。3. 基於採樣的方法。4. 減少交易的個數。
我重點看了“基於劃分的方法”改進演算法,現在簡單介紹一下實現思想:
基於劃分(partition)的演算法,這個演算法先把資料庫從邏輯上分成幾個互不相交的塊,每次單獨考慮一個分塊並 對它產生所有的頻集,然後把產生的頻集合并,用來產生所有可能的頻集,最後計算這些項集的支援度。
其中,partition演算法要注意的是分區的大小選取,要保證每個分區可以被放入到記憶體。當每個分區產生頻集後,再合并產生產生全域的候選k-項集。若在多個處理器分區,可以通過處理器之間共用一個雜湊樹來產生頻集。