本来老师是想让我学Hadoop的,也装了Ubuntu,配置了Hadoop,一时间却不知从何学起,加之自己还是想先看点自己喜欢的算法,学习Hadoop也就暂且搁置了,不过还是想问一下园子里的朋友有什么学习Hadoop好点的资料,求推荐~言归正传,继Apriori算法之后,今天来学习FP-growth算法。

和Apriori算法相比,FP-growth算法只需要对数据库进行两次遍历,从而高效发现频繁项集。对于搜索引擎公司而言,他们需要通过查看互联网上的用词来找出经常在一块出现的词对,因此这些公司就需要能够高效的发现频繁项集的方法,今天要学习的FP-growth算法就可以完成此重任。

一 FP-growth算法

1.概述

FP-growth算法是基于Apriori原理的,通过将数据集存储在FP(Frequent Pattern)树上发现频繁项集,但不能发现数据之间的关联规则。FP-growth算法只需要对数据库进行两次扫描,而Apriori算法在求每个潜在的频繁项集时都需要扫描一次数据集,所以说Apriori算法是高效的。其中算法发现频繁项集的过程是:

(1)构建FP树;

(2)从FP树中挖掘频繁项集。

2. 构建FP树

FP表示的是频繁模式,其通过链接来连接相似元素,被连起来的元素可以看成是一个链表。将事务数据表中的各个事务对应的数据项按照支持度排序后,把每个事务中的数据项按降序依次插入到一棵以 NULL为根节点的树中,同时在每个结点处记录该结点出现的支持度。

FP-growth算法的流程为:首先构造FP树,然后利用它来挖掘频繁项集。在构造FP树时,需要对数据集扫描两边,第一遍扫描用来统计频率,第二遍扫描至考虑频繁项集。下面举例对FP树加以说明。

假设存在的一个事务数据样例为,构建FP树的步骤如下:

事务ID

事务中的元素

001

r,z,h,j,p

002

z,y,x,w,v,u,t,s

003

z

004

r,x,n,o,s

005

y,r,x,z,q,t,p

006

y,z,x,e,q,s,t,m

结合Apriori算法中最小支持度的阈值,在此将最小支持度定义为3,结合上表中的数据,那些不满足最小支持度要求的将不会出现在最后的FP树中,据此构建FP树,并采用一个头指针表来指向给定类型的第一个实例,快速访问FP树中的所有元素,构建的带头指针的FP树如下:

结合绘制的带头指针表的FP树,对表中数据进行过滤,排序如下:

事务ID

事务中的元素

过滤和重排序后的事务

001

r,z,h,j,p

z,r

002

z,y,x,w,v,u,t,s

z,x,y,s,t

003

z

z

004

r,x,n,o,s

x,s,r

005

y,r,x,z,q,t,p

z,x,y,r,t

006

y,z,x,e,q,s,t,m

z,x,y,s,t

在对数据项过滤排序了之后,就可以构建FP树了,从NULL开始,向其中不断添加过滤排序后的频繁项集。过程可表示为:

根据该思想就可以实现FP树的构建,下面就采用Python进行实现。我们知道,在第二次扫描数据集时会构建一棵FP树,并采用一个容器来保存树。首先创建一个类来保存树的每一个节点,代码如下:

#coding:utf-8

from numpy import *

classtreeNode:def __init__(self, nameValue, numOccur, parentNode):

self.name=nameValue

self.count=numOccur

self.nodeLink=None

self.parent= parentNode #needs to be updated

self.children ={}definc(self,numOccur):

self.count+=numOccurdef disp(self,ind = 1):print ' '*ind,self.name,' ',self.countfor child inself.children.values():

child.disp(ind+1)'''#test

rootNode = treeNode('pyramid',9,None)

rootNode.children['eye'] = treeNode('eye',13,None)

a = rootNode.disp()

print a'''

这样,FP树对应的数据结构就建好了,现在就可以构建FP树了,FP树的构建函数如下:

#FP构建函数

def createTree(dataSet,minSup = 1):

headerTable={}for trans indataSet:for item intrans:

headerTable[item]= headerTable.get(item,0) + dataSet[trans]#记录每个元素项出现的频度

for k inheaderTable.keys():if headerTable[k] freqItemSet=set(headerTable.keys())if len(freqItemSet) == 0:#不满足最小值支持度要求的除去returnNone,Nonefor k inheaderTable:headerTable[k]=[headerTable[k],None]retTree= treeNode('Null Set',1,None)for tranSet,count indataSet.items():localD={}for item intranSet:if item infreqItemSet:localD[item]=headerTable[item][0]if len(localD) >0:orderedItems= [v[0] for v in sorted(localD.items(),key = lambda p:p[1],reverse =True)]updateTree(orderedItems,retTree,headerTable,count)returnretTree,headerTabledefupdateTree(items, inTree, headerTable, count):if items[0] ininTree.children:inTree.children[items[0]].inc(count)else:inTree.children[items[0]]=treeNode(items[0], count, inTree)if headerTable[items[0]][1] ==None:headerTable[items[0]][1] =inTree.children[items[0]]else:updateHeader(headerTable[items[0]][1], inTree.children[items[0]])if len(items) > 1:updateTree(items[1::], inTree.children[items[0]], headerTable, count)defupdateHeader(nodeToTest, targetNode):while (nodeToTest.nodeLink !=None):nodeToTest=nodeToTest.nodeLinknodeToTest.nodeLink= targetNode在运行上例之前还需要一个真正的数据集,结合之前的数据自定义数据集:defloadSimpDat():simpDat= [['r', 'z', 'h', 'j', 'p'],['z', 'y', 'x', 'w', 'v', 'u', 't', 's'],['z'],['r', 'x', 'n', 'o', 's'],['y', 'r', 'x', 'z', 'q', 't', 'p'],['y', 'z', 'x', 'e', 'q', 's', 't', 'm']]returnsimpDatdefcreateInitSet(dataSet):retDict={}for trans indataSet:retDict[frozenset(trans)]= 1return retDict运行:#testsimpDat =loadSimpDat()initSet=createInitSet(simpDat)myFPtree,myHeaderTab= createTree(initSet,3)a=myFPtree.disp()print a这样就构建了FP树,接下来就是使用它来进行频繁项集的挖掘。3. 从FP树中挖掘频繁项集在构建了FP树之后,就可以抽取频繁项集了,这里的思想和Apriori算法大致类似,首先从氮元素项集合开始,然后在此基础上逐步构建更大的集合。大致分为三个步骤:(1)从FP树中获得条件模式基;(2)利用条件模式基,构建一个条件FP树;(3)迭代重复(1)和(2),直到树包含一个元素项为止。首先,获取条件模式基。条件模式基是以所查找元素项为结尾的路径集合,表示的是所查找的元素项与树根节点之间的所有内容。结合构建FP树绘制的图,r的前缀路径就是{x,s}、{z,x,y}和{z},其中的每条前缀路径都与一个计数值有关,该计数值表示的是每条路径上r的数目。为了得到这些前缀路径,结合之前所得到的头指针表,头指针表中包含相同类型元素链表的起始指针,根据每一个元素项都可以上溯到这棵树直到根节点为止。该过程对应的代码如下:def ascendTree(leafNode, prefixPath): #ascends from leaf node to rootif leafNode.parent !=None:prefixPath.append(leafNode.name)ascendTree(leafNode.parent, prefixPath)def findPrefixPath(basePat, treeNode): #treeNode comes from header tablecondPats ={}while treeNode !=None:prefixPath=[]ascendTree(treeNode, prefixPath)if len(prefixPath) > 1:condPats[frozenset(prefixPath[1:])] =treeNode.counttreeNode=treeNode.nodeLinkreturncondPats#testsimpDat =loadSimpDat()initSet=createInitSet(simpDat)myFPtree,myHeaderTab= createTree(initSet,3)a=myFPtree.disp()b= findPrefixPath('x',myHeaderTab['x'][1])print b运行代码,与所给数据一致。接下来就可以创建条件FP树了。对于每一个频繁项,都需要创建一棵条件FP树,使用刚才创建的条件模式基作为输入,采用相同的建树代码来构建树,相应的递归发现频繁项、发现条件模式基和另外的条件树。对应的递归查找频繁项集的函数如下:defmineTree(inTree, headerTable, minSup, preFix, freqItemList):bigL= [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1])]#(sort header table)for basePat inbigL:newFreqSet=preFix.copy()newFreqSet.add(basePat)freqItemList.append(newFreqSet)condPattBases= findPrefixPath(basePat, headerTable[basePat][1])myCondTree, myHead=createTree(condPattBases, minSup)if myHead !=None:mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)结合之前的数据验证发现无误。二  从新闻网站点击流中挖掘上述在自定义的数据中队算法进行了验证,现在选取实际的数据进行测试。在这个数据集合中,包含了100万条记录,文件中的每一行包含某个用户浏览过的新闻报道,用来寻找那些至少被10万人浏览过的报道。代码如下:#从新闻网站点击流中挖掘parsedData = [line.split() for line in open('kosarak.dat').readlines()]initSet=createInitSet(parsedData)myFPtree,myHeaderTab= createTree(initSet,100000)myFreqList=[]a= mineTree(myFPtree,myHeaderTab,100000,set([]),myFreqList)b=len(myFreqList)printbprint myFreqList这样就实现了此功能。以上是我自己的总结和理解,难免有错,还望各位朋友不吝赐教~

fp算法例题_机器学习(九)—FP-growth算法相关推荐

  1. louvian算法 缺点 优化_机器学习中的优化算法(1)-优化算法重要性,SGD,Momentum(附Python示例)...

    本系列文章已转至 机器学习的优化器​zhuanlan.zhihu.com 优化算法在机器学习中扮演着至关重要的角色,了解常用的优化算法对于机器学习爱好者和从业者有着重要的意义. 这系列文章先讲述优化算 ...

  2. 最小径集的算法_机器学习的利器——集成算法

    最近在打算法竞赛的时候用到了集成算法,效果还不错,索性就总结了一篇集成算法的文章,希望能帮到正在转行的数据分析师们. 集成算法核心思想 集成算法的核心思想是通过构建并结合多个学习器来完成学习任务,也就 ...

  3. python 梯度提升树_机器学习:梯度提升算法|python与r语言代码实现

    梯度提升算法 10.1 GBM GBM(梯度提升机)是一种在处理大量数据以进行高预测的预测时使用的Boosting算法.Boosting实际上是一个学习算法的集合,它结合了几个基本估计量的预测,以便比 ...

  4. pagerank数据集_机器学习十大经典算法-PageRank(附实践代码)

    Yo, yo, check it out. 保证看完不晕倒... 如果公式让你脑瓜疼,请忽略公式,或者忽略脑瓜. Kagging咖金:推荐系统之关联规则(附实践代码)​zhuanlan.zhihu.c ...

  5. 正确率能很好的评估分类算法吗_机器学习算法优缺点对比及选择(汇总篇)

    转自:机器学习与统计学 本文的目的,是务实.简洁地盘点一番当前机器学习算法.文中内容结合了个人在查阅资料过程中收集到的前人总结,同时添加了部分自身总结,在这里,依据实际使用中的经验,将对此模型优缺点及 ...

  6. em算法怎么对应原有分类_机器学习系列之EM算法

    我讲EM算法的大概流程主要三部分:需要的预备知识.EM算法详解和对EM算法的改进. 一.EM算法的预备知识 1.极大似然估计 (1)举例说明:经典问题--学生身高问题 我们需要调查我们学校的男生和女生 ...

  7. dijkstra算法原理_这 10 大基础算法,程序员必知必会!

    来源:博客园原文地址:http://kb.cnblogs.com/page/210687/算法一:快速排序算法快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序n个项目要Ο(nlogn)次 ...

  8. 【Java数据结构与算法】第十九章 贪心算法、Prim算法和Kruskal算法

    第十九章 贪心算法.Prim算法和Kruskal算法 文章目录 第十九章 贪心算法.Prim算法和Kruskal算法 一.贪心算法 1.介绍 2.支付问题 二.Prim算法 1.最小生成树 2.介绍 ...

  9. 算法工程师9——机器学习概述(下篇-算法进阶)

    算法 9 朴素贝叶斯 10 支持向量机 11 EM算法 12 马尔科夫链 12.1 隐马尔科夫模型 13 集成学习进阶 XGboost lightGBM 必会代码 11 贝叶斯文本情感分类 12 SV ...

最新文章

  1. 软件项目管理 用户测试,1对软件研发过程中用户需求研发设计项目测试交付实施测试等流程监督管理.doc...
  2. PyTorch模型量化工具学习
  3. proteus里面没有stm32怎么办_学习STM32日志——独立看门狗实验(20.06.23)
  4. 流式计算框架Storm 编程案例部署Linux结果演示及pom依赖
  5. OpenCV形态学变换函数morphologyEx()梯度运算的使用
  6. 机器学习-LR推导及与SVM的区别
  7. 并发请求数_nginx如何限制并发连接和请求数?
  8. Future取消线程执行
  9. mysql 连接 指定字符集_关于Mysql连接池配置指定字符集的问题
  10. mysql内存报警_[MySQL生产环境] Innodb存储引擎内存报警问题处理过程_MySQL
  11. linux进程通信中有名管道的特点,linux进程通信之(四):有名管道的读与写
  12. mysql怎么查找删除重复数据_Mysql中如何查找并删除重复数据
  13. java.lang.UnsupportedOperationException: This parser does not support specification “null“ version “
  14. 关于Navicat 数据库一直激活不成功的解决方法
  15. 概率论与数理统计(下)
  16. 可以打开c语言的压缩包软件,File Magic(全格式文件打开软件)v1.9.8.19免费版
  17. 《Spring+Spring MVC+MyBatis从零开始学》傻瓜式学习笔记
  18. 从零开始学习ThingJS之创建App对象
  19. Apache Kafka 在 360 的深度实践
  20. Itext 学习笔记(六) pdf的页眉页脚

热门文章

  1. jquery将表单序列化json对象
  2. pg10 10.3 1 linux64,Install Postgresql 10 In Ubutnu 16.04 LTS
  3. java框架mybatis配置文件总结一
  4. PMO在组织结构中的作用
  5. CSV文件的转义处理
  6. oracle权限培训,Java培训-ORACLE数据库学习【2】用户权限
  7. mysql双机热备 配置文件,MYSQL 双机热备配置手册()
  8. es统计有多少个分组_ES 24 - 如何通过Elasticsearch进行聚合检索 (分组统计)
  9. [转载] Java——toArray,集合转换为数组
  10. Java中的main()方法是强制性的吗?