机器学习实战之FP-growth

1 算法流程:
(1)构建FP树
(2)从FP树种挖掘频繁项集
1.1 构建FP树
(1)创建FP树的数据结构
因为FP树比较复杂,所以需要创建一个了类来存储每个节点。
(2)构建FP树
思想:遍历数据集中每个元素,获得每个元素出现的次数,然后根据元素出现的频率,去掉不满足最小支持度的元素项。获得过滤后的频繁项集,然后开始构建FP树。构建BP树的过程就是向树中添加频繁项集的过程,这就需要第二次遍历数据集,遍历数据集中元素时,这是只考虑频繁项集,对每个频繁项根据支持度递减的次序进行排序,然后使用排序后的频繁项集进行对树的填充,填充过程为:首先建一个空树,当遍历第一组频繁项集时,将所有项集填入树中,作为树的子节点(添的时候从上到下依次添入,比如下图中第一步add{z,r}),然后,再填入下一组频繁项集时,对每个频繁项有:遍历树中的每个元素,从上到下,从左到右,如果该频繁项已存在树的子节点中,只需将该子节点的频繁项数加1即可,如果该频繁项不存在树的子节点中,就将该频繁项添加到树中,作为新的子节点,接下来添加频繁项组的过程跟上述一样,直到将所有频繁项都添加到FP树中。
下图就是五步添加频繁项到树中的例子:
这里写图片描述
实现:

def createTree(dataSet, minSup=1): #create FP-tree from dataset but don't mine
    headerTable = {}  #建FP树都是从空集开始
    #go over dataSet twice
    for trans in dataSet:#遍历一遍扫描数据集并统计每个元素项出现的频度
        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())
    #print 'freqItemSet: ',freqItemSet
    if len(freqItemSet) == 0: return None, None  #如果频繁项集为空,则退出
    for k in headerTable:  #扩展头指针表,第一个元素保存计数,第二个元素指向第一个元素项
        headerTable[k] = [headerTable[k], None] #reformat headerTable to use Node link 
    #print 'headerTable: ',headerTable
    retTree = treeNode('Null Set', 1, None) #开始构建FP树
    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)#populate tree with ordered freq itemset
    return retTree, headerTable #return tree and header table
def updateTree(items, inTree, headerTable, count):
    #每次循环都只测试第一个元素项是否作在原来的树中,以下程序都只是针对第一个元素的
    #因为每次第一个元素处理完之后,都调用后面的updateHeader(去除第一个元素函数),
    # 所以每次循环相当于遍历items中的每个元素
    if items[0] in inTree.children:
        inTree.children[items[0]].inc(count) #如果是,该元素数量+1
    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)

1.2 从FP树种挖掘频繁项集
步骤:(1)从FP树中获取条件模式基
(2)利用条件模式基,构建一个条件FP树
(3)迭代(1),(2)步骤,直到树中包含一个元素项为止。
条件模式基:所查元素项为结尾的路径集,(比如:上图中元素s的条件模式基为:{z,x,y}2,{x},1)
创建条件FP树:因为需要对每个频繁项都要挖掘频繁项集,所以对每个频繁项都要创建条件FP树。比如:
这里写图片描述
虽然s与r属于频繁项,可是{s,t}:2与{r,t}:1不频繁,所以需要去掉。
实现:

def mineTree(inTree, headerTable, minSup, preFix, freqItemList):
    bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1])]#显示每个频繁项素
    for basePat in bigL:  #遍历每个频繁项
        newFreqSet = preFix.copy()
        newFreqSet.add(basePat)
        #print 'finalFrequent Item: ',newFreqSet    #append to set
        #将频繁项存储到freqItemList集合中
        freqItemList.append(newFreqSet)
        #获取该频繁项集的条件模式基
        condPattBases = findPrefixPath(basePat, headerTable[basePat][1])
        myCondTree, myHead = createTree(condPattBases, minSup)
        if myHead != None: #3. mine cond. FP-tree
            print 'conditional tree for: ',newFreqSet
            myCondTree.disp(1)
            mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值