FP - growth 发现频繁项集

时间:2022-03-27 17:52:35

  FP - growth是一种比Apriori更高效的发现频繁项集的方法。FP是frequent pattern的简称,即常在一块儿出现的元素项的集合的模型。通过将数据集存储在一个特定的FP树上,然后发现频繁项集或者频繁项对。通常,FP-growth算法的性能比Apriori好两个数量级以上。

  FP树与一般的树结构类似,但它通过链接(Link)来连接相似元素,被连起来的元素项可以看成一个链表。

FP - growth 发现频繁项集

上图是一棵FP树,一个元素项可以在一棵FP树种出现多次,FP树的节点会存储项集的出现频率,每个项集会以路径的方式存储在树中。存在相似元素的集合会共享树的一部分,只有当集合之间完全不同时,树才会分叉。树节点上给出集合中的单个元素及其在序列中的出现次数,路径会给出该序列的出现次数。相似元素之间的链接即节点链接,用于快速发现相似项的位置。

FP - growth 发现频繁项集

  表中给出了生成上面FP树(支持度>=3)的数据集。在所有数据集中,元素项z出现了5次,集合{r,z}出现了1次,于是可以得出结论:z一定是自己本身或者和其他符号一起出现了4 次。集合{t,s,y,x,z}出现了2次,集合{t,r,y,x,z}出现1次,z自身出现了1次。因为使用的最小支持度是3,所以q,p等小于3次的元素没有出现在FP树中。

  FP树的构建过程中,需要对原始数据集进行两次扫描(Apriori算法对于每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁),第一遍对所有元素项的出现次数进行计数,用于统计每个元素的出现频率,Apriori算法告诉我们,如果某元素是不频繁的,那么包含该元素的超集也是不频繁的,所以就不需要考虑这些超集了。第二遍用于构建FP树,扫描中只考虑哪些频繁元素。

FP树的节点的类定义如下:

class treeNode:
def __init__(self, nameValue, numOccur, parentNode):
self.name = nameValue
self.count = numOccur
self.nodeLink = None
self.parent = parentNode #needs to be updated
self.children = {} def inc(self, numOccur):
self.count += numOccur def disp(self, ind=1):
print ' '*ind, self.name, ' ', self.count
for child in self.children.values():
child.disp(ind+1)

  类中包含用于存放节点名字的变量name和一个个记数值count,nodeLink变量用于链接相似的元素项。parent变量用于指向当前节点的父节点,children变量为一个字典类型,用于存放节点的子节点。inc()用于对count进行计数,disp()用于将树以文本方式显示。

  构建FP树,还需要一个字典类型的头指针表来指向给定类型的第一个实例。利用头指针表,可以快速访问FP树中一个给定类型的所有元素,同时,头指针表还用来保存FP树中每类元素的总数。

FP - growth 发现频繁项集

  构建FP树的步骤。第一次遍历数据集,计算得到每个元素项出现的频率,接下来,去掉不满足最小支持度的元素项。第二次遍历构建FP树,读入每个项集并将其添加到一条已经存在的路径中,如果该路径不存在,则创建一条心路径。每个数据集都是一个无序集合,假设有集合{z,x,y}和{y,z,r},那么在FP树中,相同项会只表示一次。为解决此问题,在将集合添加到树之前,需要对每个集合进行排序,排序基于元素项的绝对出现频率来进行。

FP - growth 发现频繁项集

  在对集合过滤和排序之后,就可以构建FP树了。从空集开始,向其中不断添加频繁项集。过滤、排序后的事物一次添加到树中,如果树中已存在现有元素,则增加现有元素的值;如果现有元素不存在,则向树添加一个分支。

FP - growth 发现频繁项集

FP树的构建代码:

def createTree(dataSet, minSup=1): #create FP-tree from dataset but don't mine
headerTable = {}
#go over dataSet twice
for trans in dataSet:#first pass counts frequency of occurance
for item in trans:
headerTable[item] = headerTable.get(item, 0) + dataSet[trans]
for k in headerTable.keys(): #remove items not meeting minSup
if headerTable[k] < minSup:
del(headerTable[k])
freqItemSet = set(headerTable.keys())
#print 'freqItemSet: ',freqItemSet
if len(freqItemSet) == 0: return None, None #if no items meet min support -->get out
for k in headerTable:
headerTable[k] = [headerTable[k], None] #reformat headerTable to use Node link
#print 'headerTable: ',headerTable
retTree = treeNode('Null Set', 1, None) #create tree
for tranSet, count in dataSet.items(): #go through dataset 2nd time
localD = {}
for item in tranSet: #put transaction items in order
if item in freqItemSet:
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)#populate tree with ordered freq itemset
return retTree, headerTable #return tree and header table def updateTree(items, inTree, headerTable, count):
if items[0] in inTree.children:#check if orderedItems[0] in retTree.children
inTree.children[items[0]].inc(count) #incrament count
else: #add items[0] to inTree.children
inTree.children[items[0]] = treeNode(items[0], count, inTree)
if headerTable[items[0]][1] == None: #update header table
headerTable[items[0]][1] = inTree.children[items[0]]
else:
updateHeader(headerTable[items[0]][1], inTree.children[items[0]])
if len(items) > 1:#call updateTree() with remaining ordered items
updateTree(items[1::], inTree.children[items[0]], headerTable, count) def updateHeader(nodeToTest, targetNode): #this version does not use recursion
while (nodeToTest.nodeLink != None): #Do not use recursion to traverse a linked list!
nodeToTest = nodeToTest.nodeLink
nodeToTest.nodeLink = targetNode

  在FP树构建完成之后,就可以利用FP树挖掘频繁项集了。思路与Apriori算法大致相似,基于FP树,首先从单元素项集合开始,然后在此基础上逐步构建更大的集合。

从FP树中抽取频繁项集的三个基本步骤:

1. 从FP树中获得条件模式基。

2.利用条件模式基,构建一个条件FP树

3.迭代重复步骤1和2,直到树包含一个元素项为止。

条件模式基(conditional pattern base)是以所查找元素项为结尾的路径集合。每一条路径其实都是一条前缀路径,一条前缀路径是介于所查找元素项与树根节点之间的所有内容。

从下表可以看出,符号r的前缀路径是{x,s}、{z,x,y}和{z}。每一条前缀路径都与一个计数值关联,该计数值等于起始元素项r的计数值。

FP - growth 发现频繁项集

  创建条件FP树:对于每一个频繁项,都要创建一棵条件FP树,以条件模式基作为输入数据,并通过构建FP树相同的代码来构建这些书。然后,我们会递归的返现频繁项、发现条件模式基,以及发现另外的条件树。假定对频繁项t创建一个条件FP树,然后对{t,y}、{t,x}、...重复该过程。元素项t的条件FP树的构建过程如下图:

FP - growth 发现频繁项集

实现代码如下:

def ascendTree(leafNode, prefixPath): #ascends from leaf node to root
if leafNode.parent != None:
prefixPath.append(leafNode.name)
ascendTree(leafNode.parent, prefixPath) def findPrefixPath(basePat, treeNode): #treeNode comes from header table
condPats = {}
while treeNode != None:
prefixPath = []
ascendTree(treeNode, prefixPath)
if len(prefixPath) > 1:
condPats[frozenset(prefixPath[1:])] = treeNode.count
treeNode = treeNode.nodeLink
return condPats def mineTree(inTree, headerTable, minSup, preFix, freqItemList):
bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1])]#(sort header table)
for basePat in bigL: #start from bottom of header table
newFreqSet = preFix.copy()
newFreqSet.add(basePat)
#print 'finalFrequent Item: ',newFreqSet #append to set
freqItemList.append(newFreqSet)
condPattBases = findPrefixPath(basePat, headerTable[basePat][1])
#print 'condPattBases :',basePat, condPattBases
#2. construct cond FP-tree from cond. pattern base
myCondTree, myHead = createTree(condPattBases, minSup)
#print 'head from conditional tree: ', myHead
if myHead != None: #3. mine cond. FP-tree
#print 'conditional tree for: ',newFreqSet
#myCondTree.disp(1)
mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)

FP - growth 发现频繁项集的更多相关文章

  1. FP-growth算法发现频繁项集(一)——构建FP树

    常见的挖掘频繁项集算法有两类,一类是Apriori算法,另一类是FP-growth.Apriori通过不断的构造候选集.筛选候选集挖掘出频繁项集,需要多次扫描原始数据,当原始数据较大时,磁盘I/O次数 ...

  2. 机器学习实战 - 读书笔记&lpar;12&rpar; - 使用FP-growth算法来高效发现频繁项集

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...

  3. 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集

    第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...

  4. 机器学习实战(Machine Learning in Action)学习笔记————08&period;使用FPgrowth算法来高效发现频繁项集

    机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集 关键字:FPgrowth.频繁项集.条件FP树.非监督学习作者:米 ...

  5. 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集

    第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...

  6. FP-growth算法高效发现频繁项集(Python代码)

    FP-growth算法高效发现频繁项集(Python代码) http://blog.csdn.net/leo_xu06/article/details/51332428

  7. FP-growth算法发现频繁项集(二)——发现频繁项集

    上篇介绍了如何构建FP树,FP树的每条路径都满足最小支持度,我们需要做的是在一条路径上寻找到更多的关联关系. 抽取条件模式基 首先从FP树头指针表中的单个频繁元素项开始.对于每一个元素项,获得其对应的 ...

  8. 使用FP-Growth算法高效发现频繁项集【zz】

    FP树构造 FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对.为了达到这样的效果,它采用了一种简洁的数据结 ...

  9. FP-growth高效频繁项集发现

    FP-growth 算法优缺点: 优点:一般快于Apriori 缺点:实现比较困难,在某些数据上性能下降 适用数据类型:标称型数据 算法思想: FP-growth算法是用来解决频繁项集发现问题的,这个 ...

随机推荐

  1. TimeStamp

    private void Form1_Load(object sender, EventArgs e) { textBox1.Text= GenerateTimeStamp(System.DateTi ...

  2. Html5&lowbar;移动前端不得不了解的html5 head 头标签

    移动前端不得不了解的html5 head 头标签   本文主要内容来自一丝的常用的 HTML 头部标签和百度FEX的HTML head 头标签. 移动端的工作已经越来越成为前端工作的重要内容,除了平常 ...

  3. uva 10911 - Forming Quiz Teams&lpar;记忆化搜索&rpar;

    题目链接:10911 - Forming Quiz Teams 题目大意:给出2 * n个选手的坐标, 要求将所有的选手分成n组, 每组两个人, 所有组的两个人之间的距离之和要最小, 输出最小值. 解 ...

  4. 每日必读&lpar;2&rpar; --Base64

    一. base64是什么? 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式.(The Base64 Conten ...

  5. JS 多选文件或者选择文件夹

    <%--文件多选--%> <input type="file" name="file" id="file" multipl ...

  6. &lpar;77&rpar;Wangdao&period;com第十五天&lowbar;JavaScript 用于数据交换的文本格式 JSON 对象

    JSON 对象 JSON (JavaScript Object Notation 的缩写) 也是一种数据,是 JavaScript 的原生对象,用来处理 JSON 格式数据.它有两个静态方法:JSON ...

  7. re正则表达式匹配字符串中的数字

    re.match(r'.*-(\d*).html',url_1).group(1) \d+匹配1次或者多次数字,注意这里不要写成*,因为即便是小数,小数点之前也得有一个数字:\.?这个是匹配小数点的, ...

  8. 高手养成计划基础篇-Linux第二季

    高手养成计划基础篇-Linux第二季   本文来源:i春秋社区-分享你的技术,为安全加点温度   前言 前面我们学习了文件处理命令和文件搜索命令,简单的了解了一下Linux,但是仅仅了解这样还不行,遇 ...

  9. gtid&lowbar;executed和gtid&lowbar;purged变量是如何初始化的

    一.官方释义 1.1.gtid_executed.gtid_purged https://dev.mysql.com/doc/refman/5.7/en/replication-options-gti ...

  10. nodejs&plus;mysql入门实例(增)

    var userAddSql = 'INSERT INTO userinfo(id,username,pwd) VALUES(0,?,?)'; var userAddSql_Params = ['Wi ...