zoukankan      html  css  js  c++  java
  • fp-growth树创建代码及详细注释

    事务集过滤重排:

    QQ图片20190117153000.png
    #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)
        
    #minSup:最小支持度
    #由于用例中存在出现次数相同的项如t和 y所以每次排序结果可能会不同从而导致最终的FP树有所不同,但应该是等价的
    def createTree(dataSet,minSup=1):
        headerTable={}
        #循环遍历数据集两次
        for trans in dataSet:#trans:事务
            for item in trans:#item:元素
                headerTable[item]=headerTable.get(item,0)+dataSet[trans]#headerTable中已有的次数+事务中出现的1次
        #❶(以下三行) 移除不满足最小支持度的元素项,headerTable中的key即为具体元素
        for k in list(headerTable.keys()):
            if headerTable[k]<minSup:
                del(headerTable[k])
        freqItemsSet=set(headerTable.keys())#转换为集合得到频繁项集(去除重复)
        #❷ 如果没有元素项满足要求, 则退出
        if len(freqItemsSet)==0:return None,None
        #第二次遍历获得头指针表(元素:元素出现次数,相似元素指针)
        for k in headerTable:
            headerTable[k]=[headerTable[k],None]
        retTree=treeNode('Null Set',1,None)#树初始化:空集:1 无父节点
        for tranSet,count in dataSet.items():
            localD={}
            #❸(以下三行) 根据全局频率对每个事务中的元素进行排序
            for item in tranSet:
                if item in freqItemsSet:
                    localD[item]=headerTable[item]#找出所有事务中的频繁项(元素:元素出现次数)集合
            if len(localD)>0:
                orderedItems=[v[0] for v in sorted(localD.items(),key=lambda p:str(p[1]),reverse=True)]
                #❹ 使用排序后的频率项集对树进行填充
                updateTree(orderedItems,retTree,headerTable,count)#orderedItems:事务中删除非频繁项并逆向排序后剩余的元素集合
        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)#不存在,直接添加,使其父节点指向inTree
            if headerTable[items[0]][1]==None:#如果头表目标节点为空,则将其指向inTree
                headerTable[items[0]][1]=inTree.children[items[0]]#更新头表
            else:#头结点指针不为空,则顺着该指针一直找到链表尾部,并将尾节点指针指向新插入节点
                updateHeader(headerTable[items[0]][1],inTree.children[items[0]])#否则,指向新节点(inTree对应孩子节点,逆序排序,后来指向的出现次数变少)
        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#链接上当前节点 
    
    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                 

    最终创建的树为(由于存在出现次数相同的元素 如t 和 y,可能会导致每次排序结果不一致从而使最终产生的树结果也不相同,但所有的树都应该是等价的):

    QQ图片20190117153053.png
    来源:本人博客
  • 相关阅读:
    Linux常用命令-centos
    USACO 2006 Open, Problem. The Country Fair 动态规划
    USACO 2007 March Contest, Silver Problem 1. Cow Traffic
    USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法
    USACO 2015 February Contest, Silver Problem 3. Superbull Prim最小生成树算法
    LG-P2804 神秘数字/LG-P1196 火柴排队 归并排序, 逆序对
    数据结构 并查集
    浴谷国庆集训 对拍
    1999 NOIP 回文数
    2010 NOIP 普及组 第3题 导弹拦截
  • 原文地址:https://www.cnblogs.com/nerd/p/10297440.html
Copyright © 2011-2022 走看看