关于 FP-Growth 算法介绍请见:FP-Growth算法的介绍。
本文主要介绍 FP-tree 的构造算法,关于伪代码请查看上面的文章。
上接:FP-Growth算法python实现;下接:FP-Growth算法之频繁项集的挖掘(python)。
tree_builder.py 文件:
#coding=utf-8
import tree_building
class Tree_builder(object):
"""tree_builder类。 作用:根据事务数据集进行数据准备及构造树."""
def __init__(self, routines, min_sup=-1, counts=[], headerTable={}):
"""类的初始化。 routines:事务数据集; min_sup:最小支持度及数; counts:每个事务出现的次数,默认为1; headerTable:头结点表,建造的FP_tree各结点的索引表。"""
self.routines = routines
self.counts = counts
self.min_sup = min_sup
self.items = self.getItems(self.routines) #获取所有项
self.sortedItems = self.getSortedItems(self.items) #对所有项进行并排序,把计数小于min_sup的项移除,生成有序的频繁1-项集
self.itemsTable = self.initItemsTable(headerTable)
self.tree = self.treeBuilding(self.counts)
def getItems(self, routines):
"""功能:扫描事务数据集,返回它的项集即各项的计数"""
items = {}
for routine in routines:
for elem in routine:
items.setdefault(elem,0)
items[elem] += 1
return items
def getSortedItems(self, items=None):
"""功能:对项集进行排序,并删去非频繁项,得到频繁1-项集"""
sortedItems = []
temp = sorted(items.iteritems(), key=lambda asd:asd[1], reverse=True) #对字典items进行排序
for elem in temp:
if elem[1] >= self.min_sup: #只取计数大于等于最小支持度及数的项
sortedItems.append(elem[0])
return sortedItems
def getSortedRoutine(self, routine):
"""功能:根据排序好的频繁1-项集对某一条事务routine进行排序"""
sortedRoutine = []
for elem in self.sortedItems:
if elem in routine:
sortedRoutine.append(elem)
return sortedRoutine
def initItemsTable(self, itemsTable):
"""功能:头结点表的初始化"""
for item in self.sortedItems:
itemsTable.setdefault(item,[])
return itemsTable
def treeBuilding(self, counts):
"""功能:逐条取出事务,控制FP_Tree树的构造"""
tree = tree_building.Tree(itemTable=self.itemsTable) #生成一个树对象
for routine in self.routines: #对事物数据集中的事务,逐条进行构造树
sortedRoutine = self.getSortedRoutine(routine) #用一条事务构造树之前先进行排序
if counts: #如果counts不为空,即是在用模式基在构造条件树,此时需要考虑模式基的计数
count = counts.pop(0)
else:
count =1
tree.addRoutine(routine=sortedRoutine, Rroot=tree.root, count=count) #用排序好的事务构造树
return tree
tree_builder.py 文件主要实现两个动作:
tree_building.py 文件:
#coding=utf-8
class Node(object):
"""Node类. 作用:开辟一个树节点"""
def __init__(self, data=-1, count=0, parent=None):
"""Node类的初始化, 一个节点信息包括:项的值,计数,父亲节点,所有孩子节点"""
self.data = data
self.count = count
self.parent = parent
self.children = {}
class Tree(object):
"""tree_growth类. 作用:建造树"""
def __init__(self, data=-1, parent=None, itemTable=None):
"""tree_growth类的初始化,开辟一个树根"""
self.root = Node(data='null', parent=self)
self.itemTable = itemTable
def addRoutine(self, routine, Rroot, count):
"""功能:根据事务routine递归构造树, Rroot是树的根节点, count是routine出现的次数(构造条件FP_tree的时候游泳)"""
if len(routine) <= 0: #如果事务为空,则终止
return
elem = routine.pop(0)
if elem in Rroot.children: #如果事务中的元素在树的已有路径上
nextNode = Rroot.children[elem] #如果事务中的元素在树的已有路径上 ,则不用新建路径
else: #否则,新建一条路径
newNode = Node(data=elem, parent=Rroot) #新建一个节点
Rroot.children.setdefault(elem,newNode) #新节点的路径放在当前节点的孩子列表中
nextNode = newNode
nextNode.count += count #更新路径上节点的计数,即加上当前节点的计数
if nextNode not in self.itemTable[elem]: #如果下一个节点是新建的,则把它压入头结点表中
self.itemTable[elem].append(nextNode)
self.addRoutine(routine=routine, Rroot=nextNode, count=count) #递归构造树
return
tree_building.py文件主要包含两个类:
代码地址: FP-Growth算法python实现(完整代码)。
备注:该代码是在 Python2.7+eclipse 环境下编写的。可在eclipse中导入项目,也可在命令行窗口用python命令执行“__init__.py”文件。