**

Apriori算法

**
Apriori 采用广度优先的搜索方式,缩小搜索空间用到了一个称为apriori的性质,其性质为:频繁项集的所有非空子集必然也是频繁的。这是很显然的,比如 同时包含项AB的记录条数肯定比只包含A的记录少。这条性质反过来也可以这么说:如果一个项集是非频繁的,那么它的超集必然也是非频繁的

算法过程如下:

输入:数据集D,支持度minsup输出:满足支持度的所有项集的集合LL1 = 发现1-项集(D); for (k=2;Lk-1 ≠Φ ;k++) {Ck = 连接剪枝生成(Lk-1, minsup)扫描D,为Ck中每个项集c 统计 c.count保留Lk ={c ∈ Ck|c.count≥min_sup}L = L ∪ Lk  }Return L

其中算法精华在于 连接剪枝生成(Lk-1, minsup) 这一步, 包含连接步和剪枝步两个动作:

  1. **连接步:**长度k-1的项连接成长度k的项;具体就是对两个k-1长的项L1和L2,必须满足前k-2个项都相同才能连接,最后把L1和L2剩下的最后一项加起来,形成k的长度的项。

  2. **剪枝步:**k项连接完成后,检查其所有k-1子集是否是频繁的,如果是,才保留作为候选项。

可以通过一张截图来演示一下apriori的过程:

对应第一张图,连接步是从第k层的项集,向下扩展一层的候选项集,剪枝步能够通过apriori性质过滤掉那些肯定非频繁的项集。

Apriori的框架其实很小,但是可以想象得到主要的两个步骤: 连接+剪枝(也就是候选集生成),以及,候选集统计是很耗费时间的。

剪枝步也需要对每个k-候选项集的k-1子集都进行一次检测,也很耗费时间;统计频繁次数是必须的,因此需要扫描数据库,经历I/O。那么有必要剪枝,直接统计会不会更好呢,虽然没有试验过,但我估计还是剪枝以后减少候选集的统计更划算。而这两个耗时的步骤在实现上如果能使用到技巧,对算法时间影响最直接。比如剪枝步中k-1候选项集需要逐一向已有的k-1频繁项集查询,这用什么数据结构最好?又如扫描数据库的时候是否能过进行一些压缩,相同的记录进行合并减少遍历次数,以及过滤掉对统计没用的记录

**简单的说apriori是先产生一批候选项集,再通过原数据集去过滤非频繁项集:先找A、B、C,检查一下通过了,再找AB、AC、AB,检查又通过了,再到ABC… 这样的广度优先的方式。

fp-growth

fp-growth是一个挖掘方式和apriori完全不一样的算法。fp-growth先从数据集中找频繁的项,再从包含这个频繁项的子数据集中找其他的频繁项,把它们俩连起来也肯定是频繁的:先找A,再在找包含A的子数据库里,找到B,就得到AB是频繁,再再包含AB的子数据库里,找到C,ABC就是频繁了。**

fp-growth采用了一个叫fp-tree 的数据结构去压缩存储数据集,放到内存里,这样以后过问原数据集的事就不必经过IO了。

Fp-tree主要是一种前缀树,和字典树(trie)接近,并且节点把项的次数也记录下了。字符的顺序有所不同,trie用的是字母表顺序,fp-tree (frequent pattern tree)用的是字母表的频率降序,这样的好处是出现次数多的项作为共享前缀的概率也大,fp-tree的压缩率就高(后面还会提到),根据apriori性质,非频繁的项没用,因此fp-tree上可以没有它们。

根据前面提到fp-growth步骤,需要找数据库上包含某个项的子数据库,不能从树根开始搜索,因此为了方便,需要把fp-tree中所有枝干、叶子上相同的项全串一起,这样项从一个起点开始,向树根遍历,就能得到包含这个项的子数据库了。这些起点和串起相同节点的链就是fp-tree的另一个部分:头表和兄弟链。头表包含树上所有的单项,并是兄弟链的起点,那么fp-tree不仅完整记录了数据库里所需的信息,还能找到对任一项找到包含了它的子数据库。

有了fp-tree,挖掘频繁项集就变得直观了。首先是压缩数据库,过滤非频繁项,得到一棵fp-tree 1号,对于一个项,比如A,通过兄弟链,遍历树找出 包含A的子树(库),又称A的条件模式树(库),英文原文叫condition pattern tree(base)。然后把这个子库当做一个新的数据库2号,过滤2号库非频繁项,建立一个小点的fp-tree 2号,那么那个A与这个2号树里的所有项,连起来肯定也是频繁的;比如有B,同理把B的条件树找出,也建立个fp-tree 3号,就能得到AB和3号树上的项连起来也肯定是频繁的。这个过程递归完成,建立不出条件子树递归就跳出去。

算法包含两个部分:

1. 是建立fp-tree:扫描一遍数据库,得到每个项的支持度,排序并过滤非频繁项;再扫描一次数据库,每条记录按顺序排序,添加到fp-tree上。2. 调用算法FP_growth(FP-tree, null)。Function Fp_growth(FP-tree, a){if(fp-tree 是单条路径){对路径上的组合b, 都连接a,输出b∪ a }else{For each 项ai in 头表{输出一个模式b= ai∪ a,其支持度 support =ai.support 构造b的条件模式库,然后构造b的条件模式树 Treeb; If (Treeb 不为空){调用算法FP_growth(Treeb,b )}}}

FP_growth是个递归算法,期间需要反复遍历树和构建fp-tree。fp-growth中判断单路径部分可以不要,最后实际结果其实是和下面部分是一样的,但是直接计算单路径产生所有组合会便捷很多。另外一点,fp-tree要按支持度降序的顺序的好处有几点?前面说了可以提高共享前缀的可能,提高压缩率,树小了,遍历的步数还能减小,寻找最优压缩的顺序是个NP难问题,因此选这个办法能有个比较好的压缩率足够了。

fp-growth虽然号称不产生候选集,但是实际上候选集产生已经在寻找条件子库的时候隐隐产生了,剪掉非频繁候选项的时候是通过建树步骤中的第一小步完成的。

fp-growth在实现上也可以有很多技巧,比如寻找条件子树的时候,同一条路径会被遍历很多次,如何有效避免(后来han自己提出,遇到扫把型的fp-tree,即上面是单路径、下面分叉的,可以把单路径所有的组合分别连接到下面的部分挖掘结果上输出,那就不用遍历上面的单路径了) 另外树上节点用什么数据结构保存指向子孙节点的指针,能同时兼顾查询时间和空间?

apriori和fp-growth之间的联系和差异

初读fp-growth算法,估计都感觉不到它和apriori有什么关系,据猜测fp-growth是从apriori的统计候选集太耗时的那里 改良开始的,希望实现候选项集的更快速的计算支持度,最后就彻底的改变的搜索频繁项集的方式。据说,两个算法的最根本的差异在于apriori是以搜索项集组合的空间作为基础,通过数据库来对照。而fp-growth是以数据库为基础,在里面寻找项集是否频繁,表现为搜索方式一个是广度优先一个是深度优先。

apriori的那剪枝步和统计支持度在fp-growth上就是不断的建fp-tree和遍历。而前者的统计需要经过的IO,后者已经压缩到内存了;但fp-growth不是在所有数据集上都比apriori强,比如在稀疏的数据集上,fp-tree每个节点可能包含非常多子孙,因此保存子孙节点的指针也是很大开销,fp-tree本来就是通过压缩使得数据集能被内存容纳,结果导致最后fp-tree起不到压缩效果适得其反。优化实现的apriori在稀疏数据集上也往往比fp-growth要快。

这里fp-growth在大部分地方是完胜了apriori,后面很多改进都是基于深度优先的思想,并且更注重实现上的技巧。现在我们也没必要去费太多精力去改进这两个算法了,因为频繁项集挖掘是个组合爆炸的时间复杂度。在2003 2004年ICDM举办过两个workshop就是专门比谁实现的频繁项集挖掘最好(搜"FIMI 03",网站里有很多的源码)。在这里想多提一点,数据挖掘中,没有算法能在所有数据集上PK掉其他算法。因此我们应该了解一种任务的多种算法,看看它们为什么和如何在不同的数据集上体现出自己的优势,这样,通过比较我们不仅能更好的理解和掌握它们的精华,更能在当我们遇到新的数据集的时候,选取合适算法甚至做出针对性的优化措施。

————————————————
版权声明:本文为CSDN博主「相国」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lgnlgn/article/details/7614892


数据频繁项集挖掘算法相关推荐

  1. 频繁项集挖掘算法在告警关联中的应用

    # 技术黑板报 # 第十期 推荐阅读时长:15min 在上一篇技术黑板报中,我们介绍了频繁项集挖掘这一问题,并讲解了Apriori算法与FP-Growth算法的技术原理.本期技术黑板报我们将主要围绕频 ...

  2. 频繁项集挖掘算法——Apriori算法

    前言 关联规则就是在给定训练项集上频繁出现的项集与项集之间的一种紧密的联系.其中"频繁"是由人为设定的一个阈值即支持度 (support)来衡量,"紧密"也是由 ...

  3. 频繁项集挖掘算法——Eclat算法

    前面介绍过的Apriori算法和FP-growth算法都是从TID项集格式(即{TID:itemset})的事务集中挖掘频繁模式,其中TID是事务标识符,而itemset是事务TID中购买的商品.这种 ...

  4. 数据挖掘---频繁项集挖掘Apriori算法的C++实现

    1 准备   首先实现这个算法是基于中南大学软件学院数据挖掘课的上机作业.作业(全英文)下载地址:http://download.csdn.net/detail/freeape/9188451 2 作 ...

  5. 频繁项集挖掘之Aprior和FPGrowth算法

    频繁项集挖掘的应用多出现于购物篮分析,现介绍两种频繁项集的挖掘算法Aprior和FPGrowth,用以发现购物篮中出现频率较高的购物组合. 基础知识 项:"属性-值"对.比如啤酒2 ...

  6. 频繁项集挖掘之apriori和fp-growth

    Apriori和fp-growth是频繁项集(frequent itemset mining)挖掘中的两个经典算法,主要的区别在于一个是广度优先的方式,另一个是深度优先的方式,后一种是基于前一种效率较 ...

  7. 关联规则—频繁项集Apriori算法

    转载地址:http://liyonghui160com.iteye.com/blog/2080531 一.前言 频繁模式和对应的关联或相关规则在一定程度上刻画了属性条件与类标号之间的有趣联系,因此将关 ...

  8. 频繁项集挖掘实战和关联规则产生

    在上篇文章<数据挖掘之Apriori频繁项集挖掘>中我们用代码手工实现了Apriori算法, 用<数据挖掘概念与技术>中的数据做检验,和书中结果一致.本篇文章, 我们基于一个更 ...

  9. 基于关联规则(Variational Autoencoders)疾病预测系统实战:(pyspark FPGrowth实现频繁项集挖掘、最后给出预测模型topK准确率和召回率)

    基于关联规则(Variational Autoencoders)疾病预测系统实战:(pyspark FPGrowth实现频繁项集挖掘.最后给出预测模型topK准确率和召回率) 目录

最新文章

  1. 计算机基础高一,2013高一计算机基础期末考试题
  2. 28篇标志性论文见证「自然语言处理NLP」2019-2020年度亮点进展
  3. Linux下的一个图形管理工具webmin
  4. task search in offline - three filters implementation
  5. mysql delete temporary denied_这些错误是什么意思?djang中的mysql
  6. 【网络】c++ socket 学习笔记(一)
  7. XSS-Game level 7
  8. Bailian2693 最远距离【序列处理】
  9. chrome浏览器下audio自动播放的hack
  10. conda pip 安装NumPy速度不佳解决方案
  11. txt代码文件怎么转换_pdf怎么转换成txt格式?小说党速来get
  12. java中substring的使用方法
  13. 超低成本的2.4G超远距离无线遥控、无线传输方案随笔
  14. 当KPI说谎:数据科学错误的高昂代价
  15. 1.工作汇报结构: 黄金圈法则结构、PREP结构、时间轴结构、金字塔结构
  16. vs2008 html5 的安装,vs2008安装教程,详细教您vs2008安装教程
  17. 伤害世界稳定服务器,伤害世界哪个服务器好_伤害世界怎么选服务器_牛游戏网...
  18. 你一定要这么多功能么?——献给希望创业的兄弟们
  19. libvirt 详解(2)
  20. android 球面 旋转 坐标系,天球坐标系和地球坐标系-GPS定位原理及应用-电子发烧友网站...

热门文章

  1. 安装maxscale实现MariaDB高可用及读写分离
  2. angular:ng-star-inserted作用
  3. js实现分数计算器的代码
  4. 十分好用的工资管理系统
  5. 图书管理系统测试报告--登录功能测试篇
  6. mafft和mega_初学者基础:进度,警报,工具提示和难以捉摸的Mega Drop
  7. 宋兰-桌面GIS应用高效开发
  8. Charles_3.11安装破解版
  9. 0基础跟着黑马程序员学微信小程序前端开发Day01
  10. 算法学习 - 归并排序