Apriori算法的基本思想

Apriori algorithm是關聯規則裏一項基本算法。是由Rakesh Agrawal和Ramakrishnan Srikant兩位在1994年提出的布爾關聯規則的頻繁項集挖掘算法(詳情:Fast Algorithms for Mining Association Rules)。算法的名字是因爲算法基於先驗知識(prior knowledge).根據前一次找到的頻繁項來生成本次的頻繁項。關聯規則的目的在於在一個數據集中找出項之間的關係,也稱之爲購物藍分析 (market basket analysis)。例如,購買佳能的顧客,有70%的可能也會買在一個月之類買HP打印機。這其中最有名的例子就是”尿布和啤酒“的故事了。
幾個概念:
關聯規則A->B的支持度support=P(AB),指的是事件A和事件B同時發生的概率。置信度confidence=P(B|A)=P(AB)/P(A),指的是發生事件A的基礎上發生事件B的概率。比如說在規則Computer => antivirus_software , 其中 support=2%, confidence=60%中,就表示的意思是所有的商品交易中有2%的顧客同時買了電腦和殺毒軟件,並且購買電腦的顧客中有60%也購買了殺毒軟件。
如果事件A中包含k個元素,那麼稱這個事件A爲k項集,並且事件A滿足最小支持度閾值的事件稱爲頻繁k項集
Apriori算法的基本思想:
過程分爲兩個步驟:第一步通過迭代,檢索出事務數據庫中的所有頻繁項集,即支持度不低於用戶設定的閾值的項集;第二步利用頻繁項集構造出滿足用戶最小信任度的規則。具體做法就是:首先找出頻繁1-項集,記爲L1;然後利用L1來產生候選項集C2,對C2中的項進行判定挖掘出L2,即頻繁2-項集;不斷如此循環下去直到無法發現更多的頻繁k-項集爲止。每挖掘一層Lk就需要掃描整個數據庫一遍。算法利用了一個性質:Apriori 性質:任一頻繁項集的所有非空子集也必須是頻繁的。意思就是說,生成一個k-itemset的候選項時,如果這個候選項有子集不在(k-1)-itemset(已經確定是frequent的)中時,那麼這個候選項就不用拿去和支持度判斷了,直接刪除。具體而言:
1) 連接步
爲找出Lk(所有的頻繁k項集的集合),通過將Lk-1(所有的頻繁k-1項集的集合)與自身連接產生候選k項集的集合。候選集合記作Ck。設l1和l2是Lk-1中的成員。記li[j]表示li中的第j項。假設Apriori算法對事務或項集中的項按字典次序排序,即對於(k-1)項集li,li[1]<li[2]<……….<li[k-1]。將Lk-1與自身連接,如果(l1[1]=l2[1])&&( l1[2]=l2[2])&&……..&& (l1[k-2]=l2[k-2])&&(l1[k-1]<l2[k-1]),那認爲l1和l2是可連接。連接l1和l2 產生的結果是{l1[1],l1[2],……,l1[k-1],l2[k-1]}。
2) 剪枝步
CK是LK的超集,也就是說,CK的成員可能是也可能不是頻繁的。通過掃描所有的事務(交易),確定CK中每個候選的計數,判斷是否小於最小支持度計數,如果不是,則認爲該候選是頻繁的。爲了壓縮Ck,可以利用Apriori性質:任一頻繁項集的所有非空子集也必須是頻繁的,反之,如果某個候選的非空子集不是頻繁的,那麼該候選肯定不是頻繁的,從而可以將其從CK中刪除。
僞代碼如下:
//算法:Apriori
//輸入:D - 事務數據庫;min_sup - 最小支持度計數閾值
//輸出:L - D中的頻繁項集
//方法:
     L1=find_frequent_1-itemsets(D); // 找出所有頻繁1項集
     For(k=2;Lk-1!=null;k++){
        Ck=apriori_gen(Lk-1); // 產生候選,並剪枝
        For each 事務t in D{ // 掃描D進行候選計數
            Ct =subset(Ck,t); // 得到t的子集
            For each 候選c 屬於 Ct
                         c.count++;
        }
        Lk={c屬於Ck | c.count>=min_sup}
}
Return L=所有的頻繁集;
 
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 //連接步:產生候選
                   if has_infrequent_subset(c,Lk-1) then
                       delete c; //剪枝步:刪除非頻繁候選
                   else add c to Ck;
                  }
          Return Ck;
 
     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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章