FP-growth算法,高效发现频繁项集,找出最短时序路径
来源:互联网 发布:python 量化交易策略 编辑:程序博客网 时间:2024/06/06 01:24
FP-growth算法
在关联规则算法中,有两部分组成:一是找到频繁项集,二是挖掘关联规则。FP-growth是一种对于“寻找频繁项集”来说效率很高的算法(不用于发现关联规则),只需要遍历数据集2遍,而Apriori算法对于每个潜在的频繁项集都会扫描数据集判定是否频繁,因此FP-growth算法的速度要比Apriori算法快。
如果只是在“找到频繁项集”方面,FP-growth的应用有很多,例如:
- 模糊搜索词匹配的时候,寻找经常一起出现的词汇;
- 识别经常出现的元素项,从而用于制定决策、推荐元素或预测时使用。
- 寻找商品售卖的最佳组合;
- 用户的最短行为路径(可根据应用场景考虑是否需要时序)
FP-growth发现频繁项集的基本过程如下:
- 构建FP树;
- 从FP树中挖掘频繁项集
【FP树的描述】
- 每个项集以路径的方式存储在树中;
- 存在相似元素的集合会共享树的一部分;
- 只有当集合(路径)之间完全不同时,树才会分叉;
- 树节点上给出集合中的单个元素及其在序列中出现的次数
- 相似项之间的链接即节点链接(node link),用于快速发现相似项的位置。
- 头指针表,指向给定类型的第一个实例。利用头指针表,可以快速访问FP树中一个给定类型的所有元素。
#!/usr/bin/env python2# -*- coding: utf-8 -*-"""Created on Sat Jul 15 20:38:33 2017代码参考《机器学习实战》@author: zhangyiwen"""##简单数据集及数据包装器def loadSimpDat(): 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']] return simpDat def createInitSet(dataSet): retDict = {} for trans in dataSet: retDict[frozenset(trans)] = 1 #如果事务有重复项,就会出错 return retDict
Step1:创建FP树的数据结构
##1. FP树的类定义class treeNode: def __init__(self,nameValue,numOccur,parentNode): self.name = nameValue #节点名字 self.count = numOccur #计数值 self.nodeLink = None #用于链接相似的元素项 self.parent = parentNode #用于指向当前节点的父节点 self.children = {} #存放子节点 #对count变量增加给定值 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)Step2:构建FP树
此处举一个例子,说明FP-growth的计算方式。
- 第一次遍历数据集,获得每个元素项的出现频率,并且去掉不满足最小支持度support的元素项,形成头指针表。
- 在将每个项集添加到FP树中的路径之前,要对项集进行“过滤及重排序”处理:a. 过滤不满足支持度的元素 b.按元素支持度由高到低排序
在对事务进行过滤和排序之后,就可以开始构建FP树了。从空寂(符号∅)开始,向其中不断添加频繁项集。过滤、排序后的事务一次添加到树中,如果树中已存在现有元素,则增加现有元素的值;如果现有元素不存在,则向树添加一个分支。
##2. FP树构建函数def createTree(dataSet, minSup=1): #默认最小支持度为1 #根据最小支持度,构建头指针表 headerTable={} for trans in dataSet: #trans表示事务项 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, headerTabledef updateTree(items, inTree, headerTable, count): #count是dataSet中item的个数 if items[0] in inTree.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) #对剩下的元素项迭代 def updateHeader(nodeToTest, targetNode): while (nodeToTest.nodeLink != None): nodeToTest = nodeToTest.nodeLink nodeToTest.nodeLink = targetNodeStep3:从一棵FP树中挖掘频繁项集
有了FP树之后,就可以抽取频繁项集了。这里的思路和Apriori算法类似:首先从单元素项集开始,然后在此基础上逐步构建更大的集合。此处利用FP树来实现上诉过程,不再需要原始数据集了:
- 从FP树中获得条件模式基(conditional pattern base);
- 利用条件模式基,构架一个条件FP树;
- 迭代重复步骤(1)和(2),直到树包含一个元素项为止。
从已经保存的头指针中的单个频繁元素项开始。对于每一个元素项,获得其对应的条件模式基(conditional pattern base)。条件模式基是以所查找元素项为结尾的路径集合。每一条路径其实都是一条前缀路径(prefix path),一条前缀路径是介于所查找元素项与根节点之间的所有内容。
可以对树穷举式搜索,得到前缀路径,但是有更高效的方法加速搜索过程:利用先前创建的头指针表,头指针表包含相同类型链表的起始指针。一旦达到每一个元素项,就可以上溯这棵树直到根节点。
##3. 发现以给定元素项结尾的所有路径def ascendTree(leafNode, prefixPath): #迭代上溯整棵树 if leafNode.parent != None: prefixPath.append(leafNode.name) ascendTree(leafNode.parent, prefixPath)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上述程序中的代码用于为给顶元素生成一个条件模式基,通过访问树中所有包含给定元素项的节点来完成。当创建树的时候,使用头指针表来指向该类型的第一个元素项,该元素项也会链接到其后续元素项。函数findPrefixPath()遍历链表直到到达结尾。每遇到一个元素项,都会调用ascendTree()来上溯FP树,并收集所有遇到的元素项的名称。该列表返回之后添加到条件模式基字典condPats中。
##测试运行效果fpgrowth.findPrefixPath('r',headerTable['r'][1])
Out[13]: {frozenset({'s', 'x'}): 1, frozenset({'z'}): 1, frozenset({'x', 'y', 'z'}): 1}
fpgrowth.findPrefixPath('z',headerTable['z'][1])
Out[14]: {}
fpgrowth.findPrefixPath('x',headerTable['x'][1])
Out[15]: {frozenset({'z'}): 3}
3.2 创建条件FP树
在创建
阅读全文
0 0
- FP-growth算法,高效发现频繁项集,找出最短时序路径
- 使用FP-growth算法来高效发现频繁项集
- 使用FP-growth算法来高效发现频繁项集
- FP-growth算法高效发现频繁项集
- 使用FP-growth算法来高效发现频繁项集
- FP-growth算法高效发现频繁项集
- 发现频繁项集FP-growth算法
- FP-growth算法高效发现频繁项集(Python代码)
- [完]机器学习实战 第十二章 使用FP-growth算法来高效发现频繁项集
- py2.7《机器学习实战》使用FP-growth算法高效发现频繁项集
- 【机器学习实战-python3】使用FP-growth算法来高效 发现频繁项集
- 机器学习之使用FP-growth算法来高效发现频繁项集
- 机器学习实战-使用FP-growth算法来高效发现频繁项集
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
- 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集
- 【机器学习实战】第12章 使用FP-growth算法来高效发现频繁项集
- 机器学习实战笔记-使用FP-growth算法来高效发现频繁项集
- 使用FP-growth算法发现频繁项集
- 网络请求 + imageloader
- 获取天气预报
- 英语分享总结
- 机器学习&深度学习&大数据&数据库 学习资料
- 欢迎使用CSDN-markdown编辑器
- FP-growth算法,高效发现频繁项集,找出最短时序路径
- NOIP2014-普及组复赛-第1题-珠心算测验
- ThreadLocal用法详解和原理
- Prime Land
- NOIP2015-普及组复赛-第2题-扫雷游戏
- 心跳包:告诉别人,我还活着
- Angular4环境安装
- HDU 4565 So Easy! (矩阵快速幂 + 向上取整)
- JavaScript数组的定义属性及使用