头歌实践教学平台-FPgrowth算法

这篇具有很好参考价值的文章主要介绍了头歌实践教学平台-FPgrowth算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

#第一关:头表建设

任务描述

本关任务:认识 FPgrowth 算法及FP树的头表构建。

相关知识

为了完成本关任务,你需要掌握:FP 树表示法及头表构建。

本节我们开始介绍一种称作 FP增长的算法。该算法采用完全不同的方法来发现频繁项集。该算法不同于 Apriori 算法的“产生测试”范型,而是使用一种称作 FP 树的紧凑数据结构组织数据,并直接从该结构中提取频繁项集。下面详细说明该方法。

FP树表示法及头表构建

FP 树是一种输入数据的压缩表示,它通过逐个读入事务,并把每个事务映射到 FP 树中的一条路径来构造。由于不同的事务可能会有若千个相同的项,因此它们的路径可能部分重叠。路径相互重叠越多,使用 FP 树结构获得的压缩的效果越好。如果 FP 树足够小,能够存放在内存中,就可以直接从这个内存中的结构提取频繁项集,而不必重复地扫描存放在硬盘上的数据。

头歌实践教学平台-FPgrowth算法,算法,数据挖掘,python


图一 构建的FP树

上图显示了一个数据集,它包含 10 个事务和 5 个项。图中还绘制了读入前 3 个事务之后FP树的结构。树中每一个结点都包括一个项的标记和一个计数,计数显示映射到给定路径的事务个数。初始,FP 树仅包含一个根结点,用符号null标记。随后,用如下方法扩充 FP 树: (1) 扫描一次数据集,确定每个项的支持度计数。丢弃非频繁项,而将频繁项按照支持度的递减排序。对于上图中的数据集,a是最频繁的项,接下来依次是b,c, d,e
该过程是头表的构建过程,主要的代码实现如下:

 
  1. # 统计各项出现次数
  2. # 第一次遍历,得到频繁一项集
  3. headerTable = {} #头表构建
  4. for k in item_count: # 剔除不满足最小支持度的项
  5. if item_count[k] >= min_support:
  6. headerTable[k] = item_count[k]
  7. freqItemSet = set(headerTable.keys()) # 满足最小支持度的频繁项集
编程要求

根据提示,在右侧编辑器BeginEnd之间补充代码,完成 头表构建的过程。

测试说明

点击评测,平台会对你编写的代码进行测试。 如程序无误,运行程序后提示程序执行成功,结果见文档输出。,输出会展示在文档中; 如程序有误,无法通过评测,且提示程序执行出错

import os
import time
from tqdm import tqdm

class Node():
    def __init__(self, node_name, count, parentNode):
        self.name = node_name
        self.count = count
        self.nodeLink = None  # 根据nideLink可以找到整棵树中所有nodename一样的节点
        self.parent = parentNode  # 父亲节点
        self.children = {}  # 子节点{节点名字:节点地址}

        
class Fp_tree():
    def update_header(self, node, targetNode):  # 更新headertable中的node节点形成的链表
        while node.nodeLink != None:
            node = node.nodeLink
        node.nodeLink = targetNode

    def update_fptree(self, items, node, headerTable):  # 用于更新fptree
        if items[0] in node.children:
            # 判断items的第一个结点是否已作为子结点
            node.children[items[0]].count += 1
        else:
            # 创建新的分支
            node.children[items[0]] = Node(items[0], 1, node)
            # 更新相应频繁项集的链表,往后添加
            if headerTable[items[0]][1] == None:
                headerTable[items[0]][1] = node.children[items[0]]
            else:
                self.update_header(headerTable[items[0]][1], node.children[items[0]])
        # 递归
        if len(items) > 1:
            self.update_fptree(items[1:], node.children[items[0]], headerTable)

    def create_fptree(self, data_set, min_support, flag=False):  # FPTree构建, 建树主函数
        '''
        根据data_set创建fp树
        header_table结构为
        {"nodename":[num,node],..} 根据node.nodelink可以找到整个树中的所有nodename
        '''

        ###########Begin##########
       


        ###########End###########
        
        if flag:
            ite = tqdm(data_set)
        else:
            ite = data_set
        for t in ite:  # 第二次遍历,建树
            localD = {}
            for item in t:
                if item in freqItemSet:  # 过滤,只取该样本中满足最小支持度的频繁项
                    localD[item] = headerTable[item][0]  # element : count
            if len(localD) > 0:
                # 根据全局频数从大到小对单样本排序
                order_item = [v[0] for v in sorted(localD.items(), key=lambda x: x[1], reverse=True)]
                # 用过滤且排序后的样本更新树
                self.update_fptree(order_item, tree_header, headerTable)
        return tree_header, headerTable

第一关通关代码

        ###########Begin##########
        # 头表构建
        item_count = {}  # 统计各项出现次数
        for t in data_set:  # 第一次遍历,得到频繁一项集
            for item in t:
                if item not in item_count:
                    item_count[item] = 1
                else:
                    item_count[item] += 1
        headerTable = {}  #头表构建
        for k in item_count:  # 剔除不满足最小支持度的项
            if item_count[k] >= min_support:
                headerTable[k] = [item_count[k], None]  # element: [count, node]
        
        freqItemSet = set(headerTable.keys())  # 满足最小支持度的频繁项集
        tree_header = Node('head node', 1, None)


        ###########End###########

第二关:FPtree构建

任务描述

本关任务:完成FPtree的构建。

相关知识

为了完成本关任务,你需要掌握:1. FP 树表示法,2.FPtree的构建。

头歌实践教学平台-FPgrowth算法,算法,数据挖掘,python

图一 构建的FP树 上节我们对FPtree做了基本认识并构建的头表,下面我们来看它整体的构造过程。初始,FP 树仅包含一个根结点,用符号null标记。随后,用如下方法扩充 FP 树: (1) 扫描一次数据集,确定每个项的支持度计数。丢弃非频繁项,而将频繁项按照支持度的递减排序。对于上图中的数据集,a是最频繁的项,接下来依次是b,c, d,e

(2) 算法第二次扫描数据集,构建 FP 树。读入第一个事务{a, b}之后,创建标记为 a 和 b 的结点。然后形成null→a→b路径,对该事务编码。该路径上的所有结点的频度计数为 1 。

(3) 读入第二个事务{b, c, d}之后,为项 b, c 和 d 创建新的结点集。然后,连接结点null→b→c→d,形成一条代表该事务的路径。该路径上的每个结点的频度计数也等于1。尽管前两个事务具有一个共同项 b ,但是它们的路径不相交,因为这两个事务没有共同的前缀。

(4) 第三个事务{a, c, d, e}与第一个事务共享一个共同前缀项 a ,所以第三个事务的路径null→a→c→d→e与第-个事务的路径null→a→b部分重叠。因为它们的路径重叠,所以结点 a 的频度计数增加为 2 ,而新创建的结点 c , d 和 e 的频度计数等于 1 。

(5) 继续该过程,直到每个事务都映射到 FP 树的一条路径。读入所有的事务后即可形成的 FP 树。

整个FP树构建的代码实现如下:

for t in ite:  # 第二次遍历,建树
    localD = {}
    for item in t:
        if item in freqItemSet:  # 过滤,只取该样本中满足最小支持度的频繁项
            localD[item] = headerTable[item][0]  # element : count
    if len(localD) > 0:
        # 根据全局频数从大到小对单样本排序
        order_item = [v[0] for v in sorted(localD.items(), key=lambda x: x[1], reverse=True)]
        # 用过滤且排序后的样本更新树
        self.update_fptree(order_item, tree_header, headerTable)

上图构建的 FP 树还包含一个连接具有相同项的结点的指针列表。这些指针用虚线表示,有助于方便快速地访问树中的项。之后将使用FP树和它的相应指针产生频繁项集。

编程要求

根据提示,在右侧编辑器BeginEnd之间补充代码,完成 FPtree的构建过程。

测试说明

点击评测,平台会对你编写的代码进行测试。 如程序无误,运行程序后提示程序执行成功,结果见文档输出。,输出会展示在文档中; 如程序有误,无法通过评测,且提示程序执行出错

源代码

import os
import time
from tqdm import tqdm

class Node():
    def __init__(self, node_name, count, parentNode):
        self.name = node_name
        self.count = count
        self.nodeLink = None  # 根据nideLink可以找到整棵树中所有nodename一样的节点
        self.parent = parentNode  # 父亲节点
        self.children = {}  # 子节点{节点名字:节点地址}

        
class Fp_tree():
    def update_header(self, node, targetNode):  # 更新headertable中的node节点形成的链表
        while node.nodeLink != None:
            node = node.nodeLink
        node.nodeLink = targetNode

    def update_fptree(self, items, node, headerTable):  # 用于更新fptree
        if items[0] in node.children:
            # 判断items的第一个结点是否已作为子结点
            node.children[items[0]].count += 1
        else:
            # 创建新的分支
            node.children[items[0]] = Node(items[0], 1, node)
            # 更新相应频繁项集的链表,往后添加
            if headerTable[items[0]][1] == None:
                headerTable[items[0]][1] = node.children[items[0]]
            else:
                self.update_header(headerTable[items[0]][1], node.children[items[0]])
        # 递归
        if len(items) > 1:
            self.update_fptree(items[1:], node.children[items[0]], headerTable)

    def create_fptree(self, data_set, min_support, flag=False):  # FPTree构建, 建树主函数
        '''
        根据data_set创建fp树
        header_table结构为
        {"nodename":[num,node],..} 根据node.nodelink可以找到整个树中的所有nodename
        '''
        ###########Begin##########
        


        ###########End##########
        return tree_header, headerTable

通关代码

        ###########Begin##########
        # 头表构建
        item_count = {}  # 统计各项出现次数
        for t in data_set:  # 第一次遍历,得到频繁一项集
            for item in t:
                if item not in item_count:
                    item_count[item] = 1
                else:
                    item_count[item] += 1
        headerTable = {}  #头表构建
        for k in item_count:  # 剔除不满足最小支持度的项
            if item_count[k] >= min_support:
                headerTable[k] = [item_count[k], None]  # element: [count, node]
        
        freqItemSet = set(headerTable.keys())  # 满足最小支持度的频繁项集
        tree_header = Node('head node', 1, None)
        
        
        # 建树
        if flag:
            ite = tqdm(data_set)
        else:
            ite = data_set
        for t in ite:  # 第二次遍历,建树
            localD = {}
            for item in t:
                if item in freqItemSet:  # 过滤,只取该样本中满足最小支持度的频繁项
                    localD[item] = headerTable[item][0]  # element : count
            if len(localD) > 0:
                # 根据全局频数从大到小对单样本排序
                order_item = [v[0] for v in sorted(localD.items(), key=lambda x: x[1], reverse=True)]
                # 用过滤且排序后的样本更新树
                self.update_fptree(order_item, tree_header, headerTable)
        ###########End##########

第三关:{e)的条件FPtree构建

任务描述

本关任务:认识 FP 增长算法的频繁项集产生。

相关知识

为了完成本关任务,你需要掌握:FP 增长算法的频繁项集产生及条件FPtree构建。

FP 增长算法的频繁项集产生

FP 增长(FP-growth)是一种以自底向上方式探索树,由FP 树产生频繁项集的算法。给定图一产生的树,算法首先查找以 e 结尾的频繁项集,接下来依次是d,c,b,最后是a。由于每一个事务都映射到FP树中的一条路径,因而通过仅考察包含特定结点(例如e)的路径,就可以发现以e结尾的频繁项集.使用与结点e相关联的指针,可以快速访问这些路径。下图a显示了所提取的路径。之后我们便可以处理这些路径,以得到频繁项集。

头歌实践教学平台-FPgrowth算法,算法,数据挖掘,python


图一 包含各结点的路径

发现以 e 结尾的频繁项集之后,算法通过处理与结点d相关联的路径,进一步寻找以 d 结尾的频繁项集。上图 b 显示了对应的路径。继续该过程,直到处理了所有与结点 c, b 和 a 相关联的路径为止。上图c、d、e分别显示了这些项的路径,而它们对应的频繁项集汇总如下:

后缀 频繁项集
e {e},{d.e},{a,d,e},{c,e},{a,e}
d {d},{c,d},{b,c,d},{a,c,d},{b,d},{a,b,d},{a,d}
c {c],{b,c},{a,b,c},{a,c}
b {b},{a,b}
a {a}

FP 增长采用分治策略将一个问题分解为较小的子问题,从而发现以某个特定后缀结尾的所有频繁项集。例如,假设对发现所有以e结尾的频繁项集感兴趣。为了实现这个目的,必须首先检查项集{e}本身是否频繁。如果它是频繁的,则考虑发现以de结尾的频繁项集子问题,接下来是ceae。依次,每一个子问题可以进一步划分为更小的子问题。通过合并这些子问题得到的结果,就可以找到所有以 e 结尾的频繁项集。这种分治策略是FP增长算法采用的关键策略。

为了更具体地说明如何解决这些子问题,考虑发现所有以e结尾的频繁项集的任务:

(1) 第一步收集包含e结点的所有路径。这些初始的路径称为前缀路径(prefix path),如图二 a 所示。

头歌实践教学平台-FPgrowth算法,算法,数据挖掘,python

图二 使用FP增长算法发现以e结尾的频繁项集

(2) 由图二a中所显示的前缀路径,通过把与结点e相关联的支持度计数相加得到 e 的支持度计数。假定最小支持度为 2 ,因为{e}的支持度是 3 ,所以它是频繁项集。

(3) 由于{e}是频繁的,因此算法必须解决发现以de、ce、 be 和ae结尾的频繁项集的子问题。在解决这些子问题之前,必须先将前缀路径转化为条件 FP 树(conditional FP-tree)。除了用于发现以某特定后缀结尾的频繁项集之外,条件 FP 树的结构与FP树类似。 条件FP树通过以下步骤得到: (a) 首先,必须更新前缀路径上的支持度计数,因为某些计数包括那些不含项e的事务。例如,图二 a 中的最右边路径null→b:2→c:2→e:1,包括并不含项 e 的事务{b,c}.因此,必须将该前缀路径上的计数调整为 1 ,以反映包含{b, c, e}的事务的实际个数。 (b) 删除 e 的结点,修剪前缀路径。删除这些结点是因为,沿这些前缀路径的支持度计数已经更新,以反映包含e的那些事务,并且发现以de, ce, be和ae结尾的频繁项集的子问题不再需要结点e的信息。 (c) 更新沿前缀路径上的支持度计数之后,某些项可能不再是频繁的。例如,结点b只出现了 1 次,它的支持度计数等于 1 ,这就意味着只有一个事务同时包含b和e。因为所有以be结尾的项集一定都是非频繁的,所以在其后的分析中可以安全地忽略 b。 创建{e}条件模式树过程的实现代码为:

 
  1. cond_pat_base = fp.find_cond_pattern_base('e', headerTable)
  2. cond_pat_dataset = [] # 将条件模式基字典转化为数组
  3. for item in cond_pat_base:
  4. item_temp = list(item)
  5. item_temp.sort()
  6. for i in range(cond_pat_base[item]):
  7. cond_pat_dataset.append(item_temp)
  8. # 创建条件模式树
  9. cond_tree, cur_headtable = fp.create_fptree(cond_pat_dataset, min_support)
编程要求

根据提示,在右侧编辑器BeginEnd之间补充代码,完成 FP条件树的构建过程。

测试说明

点击评测,平台会对你编写的代码进行测试。 如程序无误,运行程序后提示程序执行成功,结果见文档输出。,输出会展示在文档中; 如程序有误,无法通过评测,且提示程序执行出错

源代码

import os
import time
from tqdm import tqdm

class Node:
    def __init__(self, node_name, count, parentNode):
        self.name = node_name
        self.count = count
        self.nodeLink = None  # 根据nideLink可以找到整棵树中所有nodename一样的节点
        self.parent = parentNode  # 父亲节点
        self.children = {}  # 子节点{节点名字:节点地址}


class Base():
    def update_header(self, node, targetNode):  # 更新headertable中的node节点形成的链表
        while node.nodeLink != None:
            node = node.nodeLink
        node.nodeLink = targetNode

    def update_fptree(self, items, node, headerTable):  # 用于更新fptree
        if items[0] in node.children:
            # 判断items的第一个结点是否已作为子结点
            node.children[items[0]].count += 1
        else:
            # 创建新的分支
            node.children[items[0]] = Node(items[0], 1, node)
            # 更新相应频繁项集的链表,往后添加
            if headerTable[items[0]][1] == None:
                headerTable[items[0]][1] = node.children[items[0]]
            else:
                self.update_header(headerTable[items[0]][1], node.children[items[0]])
        # 递归
        if len(items) > 1:
            self.update_fptree(items[1:], node.children[items[0]], headerTable)

    def create_fptree(self, data_set, min_support, flag=False):  # FPTree构建, 建树主函数
        '''
        根据data_set创建fp树
        header_table结构为
        {"nodename":[num,node],..} 根据node.nodelink可以找到整个树中的所有nodename
        '''

        item_count = {}  # 统计各项出现次数
        for t in data_set:  # 第一次遍历,得到频繁一项集
            for item in t:
                if item not in item_count:
                    item_count[item] = 1
                else:
                    item_count[item] += 1
        headerTable = {}  #头表构建
        for k in item_count:  # 剔除不满足最小支持度的项
            if item_count[k] >= min_support:
                headerTable[k] = item_count[k]

        freqItemSet = set(headerTable.keys())  # 满足最小支持度的频繁项集
        if len(freqItemSet) == 0:
            return None, None
        for k in headerTable:
            headerTable[k] = [headerTable[k], None]  # element: [count, node]
        tree_header = Node('head node', 1, None)
        if flag:
            ite = tqdm(data_set)
        else:
            ite = data_set
        for t in ite:  # 第二次遍历,建树
            localD = {}
            for item in t:
                if item in freqItemSet:  # 过滤,只取该样本中满足最小支持度的频繁项
                    localD[item] = headerTable[item][0]  # element : count
            if len(localD) > 0:
                # 根据全局频数从大到小对单样本排序
                order_item = [v[0] for v in sorted(localD.items(), key=lambda x: x[1], reverse=True)]
                # 用过滤且排序后的样本更新树
                self.update_fptree(order_item, tree_header, headerTable)
        return tree_header, headerTable

    def find_path(self, node, nodepath):
        '''
        递归将node的父节点添加到路径
        '''
        if node.parent != None:
            nodepath.append(node.parent.name)
            self.find_path(node.parent, nodepath)

    def find_cond_pattern_base(self, node_name, headerTable):
        '''
        根据节点名字,找出所有条件模式基
        '''
        treeNode = headerTable[node_name][1]
        cond_pat_base = {}  # 保存所有条件模式基
        while treeNode != None:
            nodepath = []
            self.find_path(treeNode, nodepath)
            if len(nodepath) > 1:
                cond_pat_base[frozenset(nodepath[:-1])] = treeNode.count
            treeNode = treeNode.nodeLink
        return cond_pat_base

    def create_cond_fptree(self, headerTable, min_support, temp, freq_items, support_data):
        '''
       条件树建立的过程
        '''
        ##########Begin##########




        ############End##########
        return cur_headtable

通关代码

        ##########Begin##########
        freqs = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1][0])]  # 根据频繁项的总频次排序
        for freq in freqs:  # 对每个频繁项
            freq_set = temp.copy()
            freq_set.add(freq)
            freq_items.add(frozenset(freq_set))
            if frozenset(freq_set) not in support_data:  # 检查该频繁项是否在support_data中
                support_data[frozenset(freq_set)] = headerTable[freq][0]
            else:
                support_data[frozenset(freq_set)] += headerTable[freq][0]

            cond_pat_base = self.find_cond_pattern_base(freq, headerTable)  # 寻找到所有条件模式基
            cond_pat_dataset = []  # 将条件模式基字典转化为数组
            for item in cond_pat_base:
                item_temp = list(item)
                item_temp.sort()
                for i in range(cond_pat_base[item]):
                    cond_pat_dataset.append(item_temp)
            cond_tree, cur_headtable = self.create_fptree(cond_pat_dataset, min_support)
            if cur_headtable != None:
                self.create_cond_fptree(cur_headtable, min_support, freq_set, freq_items, support_data)  # 递归挖掘条件FP树
        return cur_headtable
        ############End##########

第四关:根据由{e)结尾的条件FPtree树计算由(e)结尾的频繁2项集

任务描述

本关任务:认识 FPgrowth 算法计算频繁项集。

相关知识

为了完成本关任务,你需要掌握:根据由{e)结尾的条件FPtree树计算由(e)结尾的频繁2项集。

FP 增长算法的频繁项集产生

上一个关卡中,我们通过(1)(2)(3)步骤已经完成了{e}条件下的FPtree构建,下面我们接着来看如何通过该条件树计算由(e)结尾的频繁2项集。

(4) FP 增长使用 e 的条件FP树来解决发现以de, ce, be和ae结尾的频繁项集的子问题。为了发现以 de 结尾的频繁项集,从项e的条件FP树收集d的所有前缀路径.通过将与结点 d 相关联的频度计数求和,得到项集{d, e}的支持度计数。因为项集{d, e}的支持度计数等于 2 ,所以它是频繁项集。接下来,算法采用第 3 步介绍的方法构建de的条件FP树。更新了支持度计数并删除了非频繁项c之后,de 的条件FP树显示在图三d中。因为该条件FP树只包含一个支持度等于最小支持度的项a,算法提取出频繁项集{a, d, e}并转到下一-个子问题,产生以ce结尾的频繁项集。处理c的前缀路径后,只发现项集{c, e}是频繁的。接下来,算法继续解决下一个子问题并发现项集{a, e}是剩下唯一的频繁项集。 使用e的条件FP树来计算以{e}结尾的频繁2项集的过程的实现如下:

 
  1. # 将条件模式基字典转化为数组
  2. # 创建条件模式树
  3. cond_tree, cur_headtable = fp.create_fptree(cond_pat_dataset, min_support)
  4. freqItemSet = set()
  5. support_data = {}
  6. if cur_headtable != None:
  7. fp.create_cond_fptree(cur_headtable, min_support, set(), freqItemSet, support_data) # 递归挖掘条件FP树
  8. print(cur_headtable)#根据e的条件FP树计算以e为结尾的频繁二项集

FP 增长是一一个有趣的算法,它展示了如何使用事务数据集的压缩表示来有效地产生频繁项集。此外,对于某些事务数据集,FP增长算法比标准的 Apriori 算法要快几个数量级。FP增长算法的运行性能依赖于数据集的压缩因子(compaction factor)。如果生成的条件P树非常茂盛(在最坏情形下,是一棵满前缀树),则算法的性能显著下降,因为算法必须产生大量的子问题,并且需要合并每个子问题返回的结果。

编程要求

根据提示,在右侧编辑器BeginEnd之间补充代码,完成 FP 增长算法寻找频繁二项集的过程。

测试说明

点击评测,平台会对你编写的代码进行测试。 如程序无误,运行程序后提示程序执行成功,结果见文档输出。,输出会展示在文档中; 如程序有误,无法通过评测,且提示程序执行出错

通关代码(我在最后面print那里加了else,也能通关)文章来源地址https://www.toymoban.com/news/detail-853409.html

import os
import time
from tqdm import tqdm

class Node:
    def __init__(self, node_name, count, parentNode):
        self.name = node_name
        self.count = count
        self.nodeLink = None  # 根据nideLink可以找到整棵树中所有nodename一样的节点
        self.parent = parentNode  # 父亲节点
        self.children = {}  # 子节点{节点名字:节点地址}


class Fp_growth():
    def update_header(self, node, targetNode):  # 更新headertable中的node节点形成的链表
        while node.nodeLink != None:
            node = node.nodeLink
        node.nodeLink = targetNode

    def update_fptree(self, items, node, headerTable):  # 用于更新fptree
        if items[0] in node.children:
            # 判断items的第一个结点是否已作为子结点
            node.children[items[0]].count += 1
        else:
            # 创建新的分支
            node.children[items[0]] = Node(items[0], 1, node)
            # 更新相应频繁项集的链表,往后添加
            if headerTable[items[0]][1] == None:
                headerTable[items[0]][1] = node.children[items[0]]
            else:
                self.update_header(headerTable[items[0]][1], node.children[items[0]])
        # 递归
        if len(items) > 1:
            self.update_fptree(items[1:], node.children[items[0]], headerTable)

    def create_fptree(self, data_set, min_support, flag=False):  # FPTree构建, 建树主函数
        '''
        根据data_set创建fp树
        header_table结构为
        {"nodename":[num,node],..} 根据node.nodelink可以找到整个树中的所有nodename
        '''

        item_count = {}  # 统计各项出现次数
        for t in data_set:  # 第一次遍历,得到频繁一项集
            for item in t:
                if item not in item_count:
                    item_count[item] = 1
                else:
                    item_count[item] += 1
        headerTable = {}  #头表构建
        for k in item_count:  # 剔除不满足最小支持度的项
            if item_count[k] >= min_support:
                headerTable[k] = item_count[k]

        freqItemSet = set(headerTable.keys())  # 满足最小支持度的频繁项集
        if len(freqItemSet) == 0:
            return None, None
        for k in headerTable:
            headerTable[k] = [headerTable[k], None]  # element: [count, node]
        tree_header = Node('head node', 1, None)
        if flag:
            ite = tqdm(data_set)
        else:
            ite = data_set
        for t in ite:  # 第二次遍历,建树
            localD = {}
            for item in t:
                if item in freqItemSet:  # 过滤,只取该样本中满足最小支持度的频繁项
                    localD[item] = headerTable[item][0]  # element : count
            if len(localD) > 0:
                # 根据全局频数从大到小对单样本排序
                order_item = [v[0] for v in sorted(localD.items(), key=lambda x: x[1], reverse=True)]
                # 用过滤且排序后的样本更新树
                self.update_fptree(order_item, tree_header, headerTable)
        return tree_header, headerTable

    def find_path(self, node, nodepath):
        '''
        递归将node的父节点添加到路径
        '''
        if node.parent != None:
            nodepath.append(node.parent.name)
            self.find_path(node.parent, nodepath)

    def find_cond_pattern_base(self, node_name, headerTable):
        '''
        根据节点名字,找出所有条件模式基
        '''
        treeNode = headerTable[node_name][1]
        cond_pat_base = {}  # 保存所有条件模式基
        while treeNode != None:
            nodepath = []
            self.find_path(treeNode, nodepath)
            if len(nodepath) > 1:
                cond_pat_base[frozenset(nodepath[:-1])] = treeNode.count
            treeNode = treeNode.nodeLink
        return cond_pat_base

    def create_cond_fptree(self, headerTable, min_support, temp, freq_items, support_data):
        '''
        # 创建条件树
        '''
        # 最开始的频繁项集是headerTable中的各元素
        freqs = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1][0])]  # 根据频繁项的总频次排序
        for freq in freqs:  # 对每个频繁项
            freq_set = temp.copy()
            freq_set.add(freq)
            freq_items.add(frozenset(freq_set))
            if frozenset(freq_set) not in support_data:  # 检查该频繁项是否在support_data中
                support_data[frozenset(freq_set)] = headerTable[freq][0]
            else:
                support_data[frozenset(freq_set)] += headerTable[freq][0]

            cond_pat_base = self.find_cond_pattern_base(freq, headerTable)  # 寻找到所有条件模式基
            cond_pat_dataset = []  # 将条件模式基字典转化为数组
            for item in cond_pat_base:
                item_temp = list(item)
                item_temp.sort()
                for i in range(cond_pat_base[item]):
                    cond_pat_dataset.append(item_temp)
            # 创建条件模式树
            cond_tree, cur_headtable = self.create_fptree(cond_pat_dataset, min_support)
            if cur_headtable != None:
                self.create_cond_fptree(cur_headtable, min_support, freq_set, freq_items, support_data)  # 递归挖掘条件FP树


    def generate_L(self, data_set, min_support):
        freqItemSet = set()
        support_data = {}
        tree_header, headerTable = self.create_fptree(data_set, min_support, flag=True)  # 创建数据集的fptree
        # 创建各频繁一项的fptree,并挖掘频繁项并保存支持度计数
        self.create_cond_fptree(headerTable, min_support, set(), freqItemSet, support_data)

        max_l = 0
        for i in freqItemSet:  # 将频繁项根据大小保存到指定的容器L中
            if len(i) > max_l: max_l = len(i)
        L = [set() for _ in range(max_l)]
        for i in freqItemSet:
            L[len(i) - 1].add(i)
        for i in range(len(L)):
            print("frequent item {}:{}".format(i + 1, len(L[i])))
        return L, support_data

    def generate_R(self, data_set, min_support, min_conf):
        L, support_data = self.generate_L(data_set, min_support)
        rule_list = []
        sub_set_list = []
        for i in range(0, len(L)):
            for freq_set in L[i]:
                for sub_set in sub_set_list:
                    if sub_set.issubset(
                            freq_set) and freq_set - sub_set in support_data:  # and freq_set-sub_set in support_data
                        conf = support_data[freq_set] / support_data[freq_set - sub_set]
                        big_rule = (freq_set - sub_set, sub_set, conf)
                        if conf >= min_conf and big_rule not in rule_list:
                            # print freq_set-sub_set, " => ", sub_set, "conf: ", conf
                            rule_list.append(big_rule)
                sub_set_list.append(freq_set)
        rule_list = sorted(rule_list, key=lambda x: (x[2]), reverse=True)
        return rule_list


if __name__ == "__main__":

    min_support = 2  # 最小支持度
    min_conf = 0.5  # 最小置信度

    data_set = [['a', 'b'], ['b', 'c', 'd'], ['a','c', 'd','e'], ['a', 'd', 'e'], ['a', 'b','c'], ['b', 'c'], ['a', 'b','c','d'],
            ['a', 'b', 'd'], ['a', 'b', 'c'], ['b', 'c', 'e']]
    #根据dataset获得规则
    fp = Fp_growth()
    rule_list = fp.generate_R(data_set, min_support, min_conf)
    print(rule_list)

    ##############Begin##################
    # 根据由{e}结尾的条件FPtree树计算由{e}结尾的频繁2项集
    # 创建Fptree
    e_condition_tree, e_header_table = fp.create_fptree([['e']], min_support)
    if e_condition_tree is not None and e_header_table is not None:  # 检查结果是否为空
        cond_pattern_base = fp.find_cond_pattern_base('e', e_header_table)
        cond_pattern_dataset = []
        for item in cond_pattern_base:
            item_temp = list(item)
            item_temp.sort()
            for i in range(cond_pattern_base[item]):
                cond_pattern_dataset.append(item_temp)
        e_cond_tree, cur_headtable = fp.create_fptree(cond_pattern_dataset, min_support)
        print(cur_headtable)  # 在这里打印 cur_headtable
    else:
        print("No frequent itemsets found for the given condition.")

到了这里,关于头歌实践教学平台-FPgrowth算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python头歌实践教学平台-python第三章作业(初级)

    第1关 判断是否直角三角形 第2关 今年多少天? 第3关 判断三角形并计算面积 第4关 身高测算 第5关 个税计算器 第6关 判断闰年 第7关 分段函数B 第8关 百分制成绩转换五分制E 第9关 正负交错数列前n项和 第10关 求数列前n项的平方和 第11关 百钱买百鸡A 第12关 用户登录

    2024年02月02日
    浏览(95)
  • 头歌实践教学平台答案(Python实训答案之循环结构)

    头歌实践教学平台答案(Python实训答案之循环结构),一共有6关, Python实训答案编程要求 本关的编程任务是补全line.py文件中的判断语句部分,具体要求如下: 填入当已处理零件数小于总零件数count partcount时的while循环判断语句; 在停电时填入break语句跳出循环。 本关涉及的代

    2024年04月13日
    浏览(76)
  • 头歌实践教学平台数据库原理与应用实训答案

    目录 实训一:数据定义和操纵(4课时) 初识MySQL数据库 第1关:创建数据库  第2关:创建表  第3关:使用主键约束 第4关:外键约束 第5关:添加常用约束 DDL语言的使用 第1关:创建数据库  第2关: 创建表  第3关:添加字段  第4关:删除字段  第5关:修改字段  第6关:添加

    2024年02月08日
    浏览(48)
  • 头歌实践教学平台Python-Python第二章作业(初级)

    第1关:三角形周长及面积 任务描述 输入的三角形的三条边a、b、c 的长度,计算并依次输出三角形的周长和面积,结果严格保留2位小数。测试用例的数据保证三角形三边数据可以构成三角形。 三角形面积计算公式: ,其中s=(a+b+c)/2。  第2关:三角函数计算 根据下面公式 计

    2024年02月08日
    浏览(155)
  • 广西民族大学高级人工智能课程—头歌实践教学实践平台—机器翻译--English to Chinese

    任务描述 本关任务:基于机器学习的思想,是一种数据驱动的研究思想,因此首先要对准备研究的数据进行处理。对于机器翻译模型,数据预处理主要分为两个方面: 标准化自然语言语句的格式 构建训练所用的语言词典 将语词转化为向量 相关知识 为了完成本关任务,你需

    2024年02月19日
    浏览(51)
  • 头歌实践教学平台-Linux网络实战(一)-DNS配置(Ubuntu系统)——保姆级教程

    见者有缘,缘来好运。诚邀各位围观我的博客【CS_GUIDER】: 我的云服务器到期了,所以这里放两个部署在码云和 GitHub 的链接: https://wlei224.gitee.io (Gitee托管,速度极快) https://wl2o2o.github.io(Github托管,点击有╰ °▽° ╯) ** 我的开源博客涵盖了 八股文 、 Java基础 、 JVM

    2023年04月20日
    浏览(50)
  • JDBC增删改查 头歌实践教学Java

       

    2024年02月04日
    浏览(53)
  • 头歌:《C语言程序设计编程实践任务》循环结构程序设计 教学团队:祁文青

    任务:求1000以内所有的水仙花数。若一个 3 位整数的各位数字的立方之和等于这个整数,称之为“水仙花数”。 注: 前面题目写过,取余可以提取刀整数的末尾数字,只要逐步提取出来判断就行。 不能改变x的值(如x10),否则循环一直无法达到x1000,会陷入死循环。 任务:输

    2024年02月05日
    浏览(66)
  • 矿物鉴定VR实践教学平台:打造全新的沉浸式学习体验

    在科技的帮助下,我们的学习和培训方式正在发生着深刻的变化。其中,虚拟现实(VR)技术带来的沉浸式学习体验,为我们提供了一种全新的学习和实践方式。本文将详细介绍一款使用VR技术的教学工具—— 矿物鉴定VR实践教学平台 。 矿物鉴定VR实践教学平台由广州华锐互

    2024年02月07日
    浏览(48)
  • 构建之法 - 软件工程实践教学:一线教师的13问

    福州大学单红老师的软工课程总结 单红⽼师在总结中,提出了13条疑惑,《构建之法》的作者邹欣⽼师就单红⽼师提出的每⼀条疑惑,给出了⾃⼰的思考,与他进⾏探讨交流。欢迎你也来参与⼀起讨论。 1. 关于软件工程和软件工程实践课,安排时机的问题?目前是大三下,对

    2024年02月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包