Apriori算法的原理及伪代码

Apriori算法的实质使用候选项集找频繁项集。 
        Apriori 算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。算法的名字基于这样的事实:算法使用频繁项集性质的先验知识, 正如我们将看到的。Apriori 使用一种称作逐层搜索的迭代方法,k-项集用于探索(k+1)-项集。首先,找出频繁1-项集的集合。该集合记作L1。L1 用于找频繁2-项集的集合L2,而L2 用于找L3,如此下去,直到不能找到频繁k-项集。找每个Lk 需要一次数据库扫描。

挖掘频繁项集

        Apriori算法的关键是如何用Lk-1找Lk?由下面的两步过程连接和剪枝组成。 
连接步:为找Lk,通过Lk-1与自己连接产生候选k-项集的集合。该候选项集的集合记作Ck。设l1和l2是Lk-1中的项集。记号li[j]表示li的第j项(例如,l1[k-2]表示l1的倒数第3项)。为方便计,假定事务或项集中的项按字典次序排序。执行连接Lk-1 Lk-1;其中,Lk-1的元素是可连接的,如果它们前(k-2)个项相同;即,Lk-1的元素l1和l2是可连接的,如果(l1[1]=l2[1])∧(l1[2]=l2[2])∧…∧(l1[k-2]=l2[k-2])∧(l1[k-1]< l2[k-1])。条件(l1[k-1]< l2[k-1])是简单地保证不产生重复。连接l1和l2产生的结果项集是l1[1]l1[2]…l1[k-1]l2[k-1]。 
剪枝步:Ck是Lk的超集;即,它的成员可以是频繁的,也可以不是频繁的,但所有的频繁k-项集都包含在Ck中。扫描数据库,确定Ck中每个候选的计数,从而确定Lk(即,根据定义,计数值不小于最小支持度计数的所有候选是频繁的,从而属于Lk)。然而,Ck可能很大,这样所涉及的计算量就很大。为压缩Ck,可以用以下办法使用Apriori性质:任何非频繁的(k-1)-项集都不是可能是频繁k-项集的子集。因此,如果一个候选k-项集的(k-1)-子集不在Lk-1中,则该候选也不可能是频繁的,从而可以由Ck中删除。这种子集测试可以使用所有频繁项集的散列树快速完成。

伪代码如下:

        算法6.2.1(Apriori) 使用逐层迭代找出频繁项集     

输入:事务数据库D;最小支持度阈值。

输出:D中的频繁项集L。

方法:  L1 = find_frequent_1_itemsets(D); //找出频繁1-项集的集合L1

           for(k = 2; Lk-1 ≠ ∅; k++) { //产生候选,并剪枝

         Ck = aproiri_gen(Lk-1,min_sup);

       for each transaction t∈D{ //扫描D进行候选计数

         Ct = subset(Ck,t); //得到t的子集

          for each candidate c∈Ct

         c.count++; //支持度计数

         }

          Lk={c∈Ck| c.count ≥min_sup} //返回候选项集中不小于最小支持度的项集

        }

     return L = ∪kLk;//所有的频繁集

第一步(连接 join)

Procedure apriori_gen(Lk-1: frequent (k-1)-itemset; min_sup: support)

1) for each itemset l1∈Lk-1

2) for each itemset l2∈Lk-1

3) if(l1[1]=l2[1])∧...∧(l1[k-2]=l2[k-2])∧(l1[k-1]<l2[k-1]) then{

4) c = l1 l2; //连接步:l1连接l2 //连接步产生候选,若K-1项集中已经存在子集c,则进行剪枝

5) if has_infrequent_subset(c,Lk-1) then

6) delete c; //剪枝步:删除非频繁候选

7) else add c to Ck;

8) }

9) return Ck;

第二步:剪枝(prune)

Procedure has_infrequent_subset(c:candidate k-itemset; Lk-1:frequent (k-1)-itemset) //使用先验定理

1) for each (k-1)-subset s of c

2) if c∉Lk-1 then

3) return TRUE;

4) return FALSE;

猜你喜欢

转载自my.oschina.net/u/3773520/blog/1648314