频繁模式挖掘总结

来源:互联网 发布:知乎 阿里 投资 编辑:程序博客网 时间:2024/05/01 09:50

概念:

         对于频繁模式挖掘,有两个基本的概念:

         support:             support = P(A,B)      

         confidence:      confidence = P(A|B) = support/P(B)


存储

         在频繁模式挖掘算法中,我们每一轮在计算所有k项集时,本来要用k维数组,可以考虑只用一维数组来存k维数组。例如用a[k] 来存a[i][j] , k= (i-1)(n-i/2)+j-i , 比较实用的方法是采用<i,j>->count的Hash方式,或者说是利用<x,y,count>来存储二项集。

算法:

         Apriori算法:

                 先决条件:transaction数据中,每个transaction的所有item都按字母序排序              

  

              1. 先扫描transaction,找出所有count>support的单个item,作为1项集

                2. 对于所有1项集,拼成2项集

                3. 扫描transaction,将不满足count>support的2项集剪枝掉

                4. 对于已剪枝的k-1项集,如果两个k-1项的前k-2项相同,则合并为k项集

                5. 对k项集再进行剪枝,再合并。。。再剪枝。。。

        

         问题:

               对于每次剪枝来说,例如对k项集进行剪枝,对于每个k项集,都要扫描所有的transaction!来计算其count,由于transaction往往较大,不可能存在内存中,所有这个过程很慢,特别是当k项集很多时



         优化策略:

                1. Hash 策略:(PCY algorithm)

                         1).在扫描k-1项集(对k-1项集进行计数)的时候,将所有k项集Hash到N个桶中,并不一定真的存在桶中,只是对桶的计数+1。

                          2).如果桶n计数<support,挡下一轮选k项集时,所有Hash到桶n的k项集都被抛弃,这样就减少了扫描整个transaction个数的次数。

                         问题:桶的个数很难确定,太小的话,没有效果,太多的话比较占内存

                  Multistage:

                         在2)后再做一下工作,首先根据k-1项集的count,对所有k-1判断是否为频繁项集,然后再做一次Hash,将满足下列条件的k-1项集Hash到新的桶中:

                                  a.此k-1项集为频繁项集

                                   b. 此k-1项集在频繁的桶中(count>support)

         然后将在原频繁桶却不在新频繁桶中的k-1项集裁减掉

                 2.Transaction Reduction

                         对于没有满足条件的k-1项集的transaction,肯定也没有满足条件的k项集,所有可以对其标记,以后不再扫描。

                         问题:对于transaction存在磁盘上的情况,即使标记某行不被读取,性能提升可能也不大。               

                 3. SON Algorithm

                     假设support为s将所有transaction分为N个partition,对每个partition做内存版的apriori算法(或Multistage), 其局部的support维s/N, 将所有partition计算出的局部频繁项集作为候选全局频繁项集,然后对所有候选集,做一次全局遍历。得到其count,判断是否为全局频繁项集。


SONAlgorithm可以写成MapReduce版本分布式计算。


应用:对于某些数据,可以根据时间或地点进行partition,然后每个partition进行计算频繁项集。但是有些情况下其实并没有必要做全局的频繁项集合并,因为其推导出的关联规则也就是局部的,基于时间地点的去使用,所以局部的频繁项集就足够了。


         FP-Tree

                 算法: 

                 1. 首先扫描全部transaction,记录每个item的count,并重写全部transaction,使得新的数据集中每个transaction中的item按count从大到小排序(这一步可以先将count<support的item剪枝掉)

                 2. 用新的transaction数据集建立FP-tree,先有一个NULL的root结点,每个transaction都按item的count从大到小的顺序从父亲到孩子,每个节点count=1,父亲结点与之前的transaction重复的就共享之前的父亲结点,将其count+1.

                 3. 对所有item,按count从小到大的顺序进行挖掘,找到其所有到root的的路径,将每个路径分析出以此item结尾的频繁项集。

                 FP-tree无需多次扫描硬盘的transaction数据,比Apriori快很多,但当数据量很大时,内存中建立FP-tree会有问题,FP-tree的大小远大于item个数,但要小于transaction数据。

但其实当support设的较高时,Apriori轮数也较少,如果可以通过partition或抽样放到内存中计算,速度应该不次于FP-Tree。

 

         Vertical Format Mining

                 算法:

                 1. 扫描所有transaction数据,将transactionnumber-> item number list 转换为item number -> transaction number list

                 2. 转换好的item number -> transaction number list 可以看做一项集,对其进行剪枝

                 3. 对不同的item number -> transaction number list 做交操作,得到item number 二项集-> transaction number list

                 4. 再交得到 三项集,四项集等等


算法总结:分布式处理,将数据都放入内存计算才是王道!Apriori算法看起来是最容易分布式处理的,而且彼此node之间很少有交互,节省了网络传输。FP-Tree也有相应的分布式处理方法,待以后研究。而Vertical Format Mining由于要与每个transaction交,所以很难做分布式。

                

频繁模式挖掘的作用:         由频繁模式推断出关联规则 

    假使J是频繁n项集。j是其中任意一个item,因此所有n个(J-j)也都是频繁项集(n-1项集)

    所以共有n个候选的关联规则:

    (J-j) ->j 

       support = P(j, J-j) = P(J)

       confidence = P(j|J-j) = P(j, J-j)/P(J-j) = support/P(J-j)

     可见对于每个关联规则来说support是相同的,confidence各不相同。

    所以将这n个候选按confidence进行筛选

    一般情况下关联规则不宜太多,所以support threshold应该设的高一些,一般为transaction个数的1%。



 

原创粉丝点击