第12章:使用FP-growth算法高效发现频繁项集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/love_image_xie/article/details/84667000

原理:通过构建FP树,在FP树中发现频繁项集。如下图所示。

       由图可知FP树包含头指针,父节点,节点的名字,节点的值,节点链接值(虚线),节点的孩子节点,因此构建类定义树结构,如下所示:

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():
            #self.children.values()是相当于treeNode类
            #对不同层级的treeNode输出不同空格
            child.disp(ind+1)

构建FP树

       第一次遍历数据集先获得每个元素出现的频率,去掉不满足最小支持度的元素;然后构建FP树,读入每个项集,并将其添加到一条已存在的路径中,如果该路径不存在,则创建一条路径。在添加每个项集时,要先对项集中的元素按照频率由大到小排序。下图展示了将非频繁项移除并重排序后的事务数据集。

对事务记录过滤和排序后就可以创建FP树了,从空集开始,向其中不断添加频繁项集。如下图所示。

代码:

def createTree(dataSet,minSup=1):
    headerTable={}
    for trans in dataSet:
        for item in trans:
            #headerTable.get(item,0)返回指定键的值,没有返回0
            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
    #重新调整headerTable以使用Node Link
    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)]
            #使用排序后的频率项对树填充
            #pdb.set_trace()
            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函数
        updateTree(items[1::], inTree.children[items[0]], headerTable, count)

def updateHeader(nodeToTest,targetNode):
    while(nodeToTest.nodeLink!=None):
        nodeToTest=nodeToTest.nodeLink
    nodeToTest.nodeLink=targetNode

猜你喜欢

转载自blog.csdn.net/love_image_xie/article/details/84667000