机器学习实战_12FP-growth算法发现高频项集
来源:互联网 发布:盛势网络剧更新时间 编辑:程序博客网 时间:2024/06/16 03:44
FP-growth算法
- 优点:一般要快于Apriori。
- 缺点:实现比较困难,在某些数据集上性能会下降。
- 适用数据类型:离散型数据。
关联分析(association analysis):从大规模数据集中寻找商品的隐含关系
项集 (itemset):包含0个或者多个项的集合称为项集
频繁项集:那些经常一起出现的物品集合
二、FP-growth算法的工作流程
首先构建FP树,然后利用它来挖掘频繁项集。
三、FP-Tree(频繁模式树)的涵义及构造
FP-growth算法不同于Apriori算法生成候选项集再检查是否频繁的”产生-测试“方法,而是使用一种称为频繁模式树(FP-Tree,PF代表频繁模式,Frequent Pattern)菜单紧凑数据结构组织数据,并直接从该结构中提取频繁项集。
1、对FP树的解读:
——–>对应的FP树———>
图中元素项z出现了5次,集合{r, z}出现了1次。于是可以得出结论:z一定是自己本身或者和其他符号一起出现了4次。
集合{t, s, y, x, z}出现了2次,集合{t, r, y, x, z}出现了1次,z本身单独出现1次。
就像这样,FP树的解读方式是读取某个节点开始到根节点的路径。
路径上的元素构成一个频繁项集,开始节点的值表示这个项集的支持度。
根据图,我们可以快速读出项集{z}的支持度为5、项集{t, s, y, x, z}的支持度为2、项集{r, y, x, z}的支持度为1、项集{r, s, x}的支持度为1。
FP树中会多次出现相同的元素项,也是因为同一个元素项会存在于多条路径,构成多个频繁项集。
但是频繁项集的共享路径是会合并的,如图中的{t, s, y, x, z}和{t, r, y, x, z}
和之前一样,我们取一个最小阈值,出现次数低于最小阈值的元素项将被直接忽略。
图中将最小支持度设为3,所以q和p没有在FP中出现。
2、为构建FP树,需要对原始数据集扫描两遍。
第一遍对所有元素项的出现次数进行计数。数据库的第一遍扫描用来统计出现的频率,而第二遍扫描中只考虑那些频繁元素。
2.1 元素项排序
上文提到过,FP树会合并相同的频繁项集(或相同的部分)。
因此为判断两个项集的相似程度需要对项集中的元素进行排序(不过原因也不仅如此,还有其它好处)。
排序基于元素项的绝对出现频率(总的出现次数)来进行。
在第二次遍历数据集时,会读入每个项集(读取),去掉不满足最小支持度的元素项(过滤),然后对元素进行排序(重排序)。
对示例数据集进行过滤和重排序的结果如下:
2.2 构建FP树
在对事务记录过滤和排序之后,就可以构建FP树了。从空集开始,将过滤和重排序后的频繁项集一次添加到树中。如果树中已存在现有元素,则增加现有元素的值;如果现有元素不存在,则向树添加一个分支。对前两条事务进行添加的过程:
算法:构建FP树
输入:数据集、最小值尺度
输出:FP树、头指针表
1. 遍历数据集,统计各元素项出现次数,创建头指针表
2. 移除头指针表中不满足最小值尺度的元素项
3. 第二次遍历数据集,创建FP树。对每个数据集中的项集:
3.1 初始化空FP树
3.2 对每个项集进行过滤和重排序
3.3 使用这个项集更新FP树,从FP树的根节点开始:
3.3.1 如果当前项集的第一个元素项存在于FP树当前节点的子节点中,则更新这个子节点的计数值
3.3.2 否则,创建新的子节点,更新头指针表
3.3.3 对当前项集的其余元素项和当前元素项的对应子节点递归3.3的过程
def creatTree(dataSet,minSup=1): headerTable = {} for trans in dataSet : # 遍历扫描数据集并统计每个元素项出现的频度 for item in trans : headerTable[item] = headerTable.get(item,0 ) + dataSet[trans] for k in headerTable.keys(): # 移除不满足最小支持度的元素项 if headerTable[k] < minSup: del (headerTable[k]) freqItemSet = set(headerTable.keys()) if len(freqItemSet) == 0 :return None,None for k in headerTable: headerTable[k] = [headerTable[k],None] # 扩展 retTree = treeNode('Null Set',1,None) for tranSet ,count in dataSet.items(): localD={} for item in tranSet :# 根据全局频率对每个事务中的元素进行排序 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) # 使用排序后的频率项对树进行填充 return retTree,headerTable
注解
dataSet[trans]实际获得了这个trans集合的出现次数(在本例中均为1),
同样“for tranSet, count in dataSet.items():”获得了tranSet和count分别表示一个项集和该项集的出现次数。 这样做是为了适应后面在挖掘频繁项集时生成的条件FP树。
辅助函数
def updateTree (items,inTree,headerTable,count): # 检查测试事务中的第一个元素是否作为子节点存在 # 如果是,更新该元素项的计数 if items[0] in inTree.children: inTree.children[items[0]].inc(count) #如果不存在,则创建一个新的treeNode并将其作为一个直接点添加到树中 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函数 updateTree(items[1::], inTree.children[items[0]],headerTable,count)
q确保节点链接指向树中该元素项的每一个实例
def updateHeader(nodeToTest,targetNode): while(nodeToTest.nodeLink != None): nodeToTest = nodeToTest.nodeLink nodeToTest.nodeLink = targetNode
这个函数其实只做了一件事,就是获取头指针表中该元素项对应的单链表的尾节点,然后将其指向新节点targetNode。
四、根据FP-Tree树查找频繁项集
从FP树中抽取频繁项集的三个基本步骤如下:
从FP树中获得条件模式基;
利用条件模式基,构建一个条件FP树;
迭代重复步骤1步骤2,直到树包含一个元素项为止。
1. 抽取条件模式基
条件模式基是以所查找元素项为结尾的路径集合。
每一条路径其实都**是一条前缀路径(prefix path)。
简而言之,一条前缀路径是介于所查找元素项与树根节点之间的所有内容。
每一个频繁元素项的所有前缀路径(条件模式基)为
z存在于路径{z}中,因此前缀路径为空,另添加一项该路径中z节点的计数值5构成其条件模式基;
r存在于路径{r, z}、{r, y, x, z}、{r, s, x}中,分别获得前缀路径{z}、{y, x, z}、{s, x},
另添加对应路径中r节点的计数值(均为1)构成r的条件模式基;以此类推。
前缀路径将在下一步中用于构建条件FP树,暂时先不考虑。
如何发现某个频繁元素项的所在的路径?
利用先前创建的头指针表和FP树中的相似元素节点指针,我们已经有了每个元素对应的单链表,因而可以直接获取。
def findPrefixPath(basePat,treeNode): condPats = {} while treeNode != None: prefixPath = [] ascendTree(treeNode,prefixPath) if len(prefixPath)>1 : condPats[frozenset(prefixPath[1:])] = treeNode.count treeNode = treeNode.nodeLink return condPats
该函数代码用于为给定元素项生成一个条件模式基(前缀路径),
这通过访问树中所有包含给定元素项的节点来完成。
参数basePet表示输入的频繁项,treeNode为当前FP树种对应的第一个节点(可在函数外部通过headerTable[basePat][1]获取)。
函数返回值即为条件模式基condPats,用一个字典表示,键为前缀路径,值为计数值。
辅助函数
迭代上溯整棵树
def ascendTree(leafNode,prefixPath): if leafNode.parent != None: prefixPath.append (leafNode.name) ascendTree(leafNode.parent,prefixPath)
2. 创建条件FP树
对于每一个频繁项,都要创建一棵条件FP树。
可以使用刚才发现的条件模式基作为输入数据,并通过相同的建树代码来构建这些树。
例如,对于r,即以“{x, s}: 1, {z, x, y}: 1, {z}: 1”为输入,调用函数createTree()获得r的条件FP树;
对于t,输入是对应的条件模式基“{z, x, y, s}: 2, {z, x, y, r}: 1”。
3. 递归查找频繁项集
1. 初始化一个空列表preFix表示前缀
2. 初始化一个空列表freqItemList接收生成的频繁项集(作为输出)
3. 对headerTable中的每个元素basePat(按计数值由小到大),递归:
3.1 记basePat + preFix为当前频繁项集newFreqSet
3.2 计算t的条件FP树(myCondTree、myHead)
3.3 当条件FP树不为空时,继续下一步;否则退出递归
3.4 以myCondTree、myHead为新的输入,以newFreqSet为新的preFix,外加freqItemList,递归这个过程
有了FP树和条件FP树,我们就可以在前两步的基础上递归得查找频繁项集。
递归的过程是这样的:
输入:我们有当前数据集的FP树(inTree,headerTable)
代码为:
def mineTree(inTree,headerTable,minSup,preFix,freqItemList): bigL =[v[0] for v in sorted(headerTable.items(),key=lambda p:p[1])] for basePat in bigL: newFreqSet = preFix.copy() newFreqSet.add(basePat) freqItemList.append(newFreqSet) # 将每一个频繁项添加到频繁项集列表中 condPattBases = findPrefixPath(basePat,headerTable[basePat][1]) myCondTree,myHead = creatTree(condPattBases,minSup) # 计算条件FP树 if myHead!= None: print 'conditional tree for: ',newFreqSet myCondTree.disp(1) mineTree(myCondTree,myHead,minSup,newFreqSet,freqItemList)
五、总结
FP-growth算法是一种用于发现数据集中频繁模式的有效方法。
FP-growth算法利用Apriori原则,执行更快。
Apriori算法产生候选项集,然后扫描数据集来检查它们是否频繁。
由于只对数据集扫描两次,因此FP-growth算法执行更快。
在FP-growth算法中,数据集存储在一个称为FP树的结构中。
FP树构建完成后,可以通过查找元素项的条件基及构建条件FP树来发现频繁项集。
该过程不断以更多元素作为条件重复进行,直到FP树只包含一个元素为止。
- 机器学习实战_12FP-growth算法发现高频项集
- [完]机器学习实战 第十二章 使用FP-growth算法来高效发现频繁项集
- py2.7《机器学习实战》使用FP-growth算法高效发现频繁项集
- 【机器学习实战-python3】使用FP-growth算法来高效 发现频繁项集
- 机器学习实战-使用FP-growth算法来高效发现频繁项集
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
- 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
- 机器学习实战笔记-使用FP-growth算法来高效发现频繁项集
- 《机器学习实战》笔记之十二——使用FP-Growth算法来高效发现频繁项集
- 代码注释:机器学习实战第12章 使用FP-growth算法来高效发现频繁项集
- 机器学习实战代码详解(12)使用FP-growth算法来高效发现频繁集
- 机器学习之使用FP-growth算法来高效发现频繁项集
- 机器学习:FP-growth 发现频繁项集
- 机器学习之-使用FP-growth算法来高效发现频繁项集-具体怎么实现及应用
- 机器学习实战--fp-growth
- 发现频繁项集FP-growth算法
- 机器学习实战之FP-growth
- xencenter如何安装Centos7虚拟机系统
- uploadify文件上传以及预览
- Python字符串常用方法收藏
- Java趣味赏玩
- 类、对象、属性、方法和事件的概念辨析
- 机器学习实战_12FP-growth算法发现高频项集
- CardStackView使用教程
- Uva12096
- SQL 查询优化 索引优化
- RecyclerView中Adapter调用notifyDataSetChanged无效时的解决方案
- 如何监控Android模拟器的HTTP访问情况
- 基本算法------贪心
- windows安装redis
- tensorflow在Windows上的安装