FP-growth算法发现频繁项集——发现频繁项集

1. FP-growth算法概述

FP-growth算法是一种用于发现频繁项集的挖掘算法。它是由Han et al.于2000年提出的。根据数据挖掘的定义,频繁项集是指在数据集中经常出现在一起的物品集合。FP-growth算法是一种快速、高效的挖掘算法。相比于Apriori算法,它无需生成候选项集,从而减少了时间和空间的开销,能够非常快速地发现频繁项集。

2. FP-growth算法原理

2.1 FP树的构建

FP-growth算法的核心是FP树,是一种用于存储频繁项集信息的数据结构。FP树由树结构和头指针表构成。其中,树结构用于存储频繁项集,头指针表则连接相同元素项的链表。

在构建FP树之前,需对数据集进行处理。首先,需要对数据集进行去重处理,并按照项集出现次数进行排序。然后,根据排序后的项集,利用每个项集中的元素构建节点,频数则存储在节点上。

FP树的构建采用递归方式进行,每次插入一个项集,从根节点开始遍历。如果已经存在相同的元素,则加上其频数,并继续遍历;否则,新建节点并挂在当前节点下面,并进行头指针表连接。最后,构建完成的FP树就是一个由节点和指针构成的树结构。

2.2 FP-growth的递归流程

FP-growth算法的递归过程由两部分组成:挖掘频繁项集和创建条件FP树。

挖掘频繁项集是一个基于递归的过程。首先,遍历头指针表,将每个元素项单独作为频繁项加入到频繁项集中。然后,从头指针表中选择一个元素项作为“基础元素”,并挖掘其对应的频繁项集。从而得到满足条件的频繁项集。

创建条件FP树是指构建以“基础元素”为根节点的子FP树。在创建条件FP树时,需对数据集进行预处理,去掉不满足条件的项。然后,针对新的数据集,构建FP树。

以上两部分递归过程反复进行,直到FP树不再包含任何元素项,或者只剩下一个元素项。

3. FP-growth算法流程

FP-growth算法的流程如下:

1. 对数据集进行预处理,去掉不满足条件的项。

2. 构建FP树。

3. 按照频繁度从大到小遍历FP树中的元素,构建条件FP树。

4. 对条件FP树进行递归挖掘,得到满足条件的频繁项集。

4. FP-growth算法优缺点

4.1 优点

FP-growth算法的优点主要体现在以下几个方面:

1. 相比于Apriori算法,FP-growth算法无需生成候选项集,从而减少了时间和空间的开销。

2. 由于FP树的特殊结构,FP-growth算法能够非常高效地挖掘频繁项集。

3. FP-growth算法不受项集中元素个数的限制,可以处理大规模的数据集。

4.2 缺点

FP-growth算法的缺点主要体现在以下几个方面:

1. 构建FP树的过程需要遍历整个数据集,因此,构建FP树可能会消耗大量的内存。

2. 构建条件FP树的过程需要在FP树上进行多次递归,因此,对于数据集中包含大量元素的频繁项集而言,递归次数可能较多,效率较低。

5. FP-growth算法应用案例

以下是使用FP-growth算法进行商品推荐的一个简单案例:

假设有一个在线商城,用户购买商品时,系统需要向用户推荐其他可能感兴趣的商品。为此,我们需要通过挖掘历史用户购买记录,发现频繁购买项集,从而推荐新的商品。

首先,根据历史用户购买记录,可以构建一个购买项集。然后,使用FP-growth算法挖掘频繁购买项集。最后,根据频繁购买项集,可以推荐与用户当前购买行为相似的商品。

6. 代码实现

以下是使用Python语言实现FP-growth算法的一个简单示例:

class TreeNode:

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

self.name = nameValue

self.count = numOccur

self.nodeLink = None

self.parent = parentNode

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)

def createTree(dataSet, minSup=1):

headerTable = {}

for trans in dataSet:

for item in trans:

headerTable[item] = headerTable.get(item, 0) + dataSet[trans]

for k in list(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

def updateTree(items, inTree, headerTable, count):

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 = targetNode

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

def mineTree(inTree, headerTable, minSup, preFix, freqItemList):

bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1][0])]

for basePat in bigL:

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)

data = [['a', 'b', 'd', 'f'], ['b', 'c', 'e'], ['a', 'b', 'c', 'e', 'f'], ['a', 'd', 'e'], ['a', 'f'], ['a', 'b', 'c', 'f'], ['b', 'd'], ['b', 'c', 'd', 'f'], ['b', 'f'], ['a', 'b', 'c', 'e', 'f']]

dataSet = {}

for i in range(len(data)):

dataSet[frozenset(data[i])] = 1

minSup = 2

myFPtree, myHeaderTab = createTree(dataSet, minSup)

myFreqList = []

mineTree(myFPtree, myHeaderTab, minSup, set([]), myFreqList)

print(myFreqList)

后端开发标签