2023年高教社杯 国赛数学建模思路 - 案例:FPTree-频繁模式树算法

news2024/11/17 20:46:37

文章目录

    • 算法介绍
    • FP树表示法
    • 构建FP树
    • 实现代码
  • 建模资料

## 赛题思路

(赛题出来以后第一时间在CSDN分享)

https://blog.csdn.net/dc_sinor?type=blog

算法介绍

FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模式树算法,他与Apriori算法一样也是用来挖掘频繁项集的,不过不同的是,FP-Tree算法是Apriori算法的优化处理,他解决了Apriori算法在过程中会产生大量的候选集的问题,而FP-Tree算法则是发现频繁模式而不产生候选集。但是频繁模式挖掘出来后,产生关联规则的步骤还是和Apriori是一样的。

常见的挖掘频繁项集算法有两类,一类是Apriori算法,另一类是FP-growth。Apriori通过不断的构造候选集、筛选候选集挖掘出频繁项集,需要多次扫描原始数据,当原始数据较大时,磁盘I/O次数太多,效率比较低下。FPGrowth不同于Apriori的“试探”策略,算法只需扫描原始数据两遍,通过FP-tree数据结构对原始数据进行压缩,效率较高。

FP代表频繁模式(Frequent Pattern) ,算法主要分为两个步骤:FP-tree构建、挖掘频繁项集。

FP树表示法

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

一颗FP树如下图所示:
  在这里插入图片描述
通常,FP树的大小比未压缩的数据小,因为数据的事务常常共享一些共同项,在最好的情况下,所有的事务都具有相同的项集,FP树只包含一条节点路径;当每个事务都具有唯一项集时,导致最坏情况发生,由于事务不包含任何共同项,FP树的大小实际上与原数据的大小一样。

FP树的根节点用φ表示,其余节点包括一个数据项和该数据项在本路径上的支持度;每条路径都是一条训练数据中满足最小支持度的数据项集;FP树还将所有相同项连接成链表,上图中用蓝色连线表示。

为了快速访问树中的相同项,还需要维护一个连接具有相同项的节点的指针列表(headTable),每个列表元素包括:数据项、该项的全局最小支持度、指向FP树中该项链表的表头的指针。
  在这里插入图片描述

构建FP树

现在有如下数据:

在这里插入图片描述

FP-growth算法需要对原始训练集扫描两遍以构建FP树。

第一次扫描,过滤掉所有不满足最小支持度的项;对于满足最小支持度的项,按照全局最小支持度排序,在此基础上,为了处理方便,也可以按照项的关键字再次排序。
在这里插入图片描述

第二次扫描,构造FP树。

参与扫描的是过滤后的数据,如果某个数据项是第一次遇到,则创建该节点,并在headTable中添加一个指向该节点的指针;否则按路径找到该项对应的节点,修改节点信息。具体过程如下所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
 从上面可以看出,headTable并不是随着FPTree一起创建,而是在第一次扫描时就已经创建完毕,在创建FPTree时只需要将指针指向相应节点即可。从事务004开始,需要创建节点间的连接,使不同路径上的相同项连接成链表。

实现代码

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:
        fset = frozenset(trans)
        retDict.setdefault(fset, 0)
        retDict[fset] += 1
    return retDict

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) + 1

    #根据最小支持度过滤
    lessThanMinsup = list(filter(lambda k:headerTable[k] < minSup, headerTable.keys()))
    for k in lessThanMinsup: del(headerTable[k])

    freqItemSet = set(headerTable.keys())
    #如果所有数据都不满足最小支持度,返回None, None
    if len(freqItemSet) == 0:
        return None, None

    for k in headerTable:
        headerTable[k] = [headerTable[k], None]

    retTree = treeNode('φ', 1, None)
    #第二次遍历数据集,构建fp-tree
    for tranSet, count in dataSet.items():
        #根据最小支持度处理一条训练样本,key:样本中的一个样例,value:该样例的的全局支持度
        localD = {}
        for item in tranSet:
            if item in freqItemSet:
                localD[item] = headerTable[item][0]

        if len(localD) > 0:
            #根据全局频繁项对每个事务中的数据进行排序,等价于 order by p[1] desc, p[0] desc
            orderedItems = [v[0] for v in sorted(localD.items(), key=lambda p: (p[1],p[0]), reverse=True)]
            updateTree(orderedItems, retTree, headerTable, count)
    return retTree, headerTable


def updateTree(items, inTree, headerTable, count):
    if items[0] in inTree.children:  # check if orderedItems[0] in retTree.children
        inTree.children[items[0]].inc(count)  # incrament count
    else:  # add items[0] to inTree.children
        inTree.children[items[0]] = treeNode(items[0], count, inTree)
        if headerTable[items[0]][1] == None:  # update header table
            headerTable[items[0]][1] = inTree.children[items[0]]
        else:
            updateHeader(headerTable[items[0]][1], inTree.children[items[0]])

    if len(items) > 1:  # call updateTree() with remaining ordered items
        updateTree(items[1:], inTree.children[items[0]], headerTable, count)


def updateHeader(nodeToTest, targetNode):  # this version does not use recursion
    while (nodeToTest.nodeLink != None):  # Do not use recursion to traverse a linked list!
        nodeToTest = nodeToTest.nodeLink
    nodeToTest.nodeLink = targetNode

simpDat = loadSimpDat()
dictDat = createInitSet(simpDat)
myFPTree,myheader = createTree(dictDat, 3)
myFPTree.disp()

上面的代码在第一次扫描后并没有将每条训练数据过滤后的项排序,而是将排序放在了第二次扫描时,这可以简化代码的复杂度。

控制台信息:

在这里插入图片描述

建模资料

资料分享: 最强建模资料
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/928720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在腾讯云服务器OpenCLoudOS系统中安装Jenkins(有图详解)

Jenkins介绍 Jenkins是一个开源软件项目&#xff0c;是基于java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件的持续集成变成可能。 将项目代码的svn地址配置在Jenkins&#xff0c;就可以直接在Je…

SPI2外设驱动-W25Q64 SPI接口初始化

前言 &#xff08;1&#xff09;本系列是基于STM32的项目笔记&#xff0c;内容涵盖了STM32各种外设的使用&#xff0c;由浅入深。 &#xff08;2&#xff09;小编使用的单片机是STM32F105RCT6&#xff0c;项目笔记基于小编的实际项目&#xff0c;但是博客中的内容适用于各种单片…

Vue实现父子组件相互传值

在Vue中&#xff0c;父组件可以通过以下几种方式获取子组件传递的值&#xff1a; 1.Props&#xff08;属性&#xff09;&#xff1a;父组件通过在子组件上定义属性&#xff08;props&#xff09;&#xff0c;将数据传递给子组件。子组件在使用props接收数据后&#xff0c;父组…

【C++】C++ 引用详解 ③ ( 函数返回值不能是 “ 局部变量 “ 的引用或指针 | 函数内的 “ 局部变量 “ 的引用或指针做函数返回值无意义 )

文章目录 一、函数返回值不能是 " 局部变量 " 的引用或指针1、引用通常做右值2、函数返回值特点3、函数内的 " 局部变量 " 的引用或指针做函数返回值无意义 二、代码示例 - " 局部变量 " 引用或指针做函数返回值测试 一、函数返回值不能是 "…

为什么要使用IP地址进行定位

IP地址定位是一种以互联网协议地址&#xff08;IP地址&#xff09;为基础的技术&#xff0c;它能够准确地确定一个设备在互联网上的位置。这种技术的应用范围非常广泛&#xff0c;从个人用户到企业机构甚至是国家安全和网络安全等领域都需要使用IP地址定位。 首先&#xff0c;I…

uniapp接入广告的问题总结

Uniapp官方解决方案 uni-app 支持接入uni-ad广告联盟&#xff0c;开发者可实现一次开发&#xff0c;多端变现。 uni-ad 支持开屏、信息流、激励视频、视频流、悬浮红包、推送等丰富的广告形式&#xff1b; uni-ad 聚合了全网所有主流广告源&#xff0c;包括腾讯优量汇、字节…

MIA文献阅读 ——医学图像处理在慢性肾脏疾病评估中的最新进展【2021】

目录 0 摘要1 引言2 磁共振成像(MRI)2.1 扩散磁共振成像2.1.1 扩散加权成像(DWI)2.1.2 扩散张量成像(DTI) 2.2 血氧水平依赖成像2.3 动脉自旋标记2.4 动态对比增强磁共振成像2.5 T1和T2映射2.6 磁化转移磁共振成像2.7 磁共振弹性成像2.8 其他磁共振成像技术 3 其他成像方式3.1 …

学习记录——FeatEnHancer

FeatEnHancer: Enhancing Hierarchical Features for Object Detection and Beyond Under Low-Light Vision 一种适用于任意低光照任务增强方法 ICCV 2023 提出了FeatEnHancer&#xff0c;一种用于低光照视觉任务的增强型多尺度层次特征的新方法。提议的解决方案重点增强相关特…

HHDESK实用工具新增

1 Ping测试 此功能可以很方便的测试&#xff0c;与需要连接的IP间是否畅通。 首页点击工具——网络——ping测试&#xff1b; 弹出对话框&#xff0c;在框内填写需要连接的IP&#xff0c;点击搜索即可。 2 Port测试 本功能用以测试连接IP的特定端口是否畅通。 首页——…

Android App的设计规范

Android App 设计规范是为开发者和设计师提供的一系列准则和建议&#xff0c;以确保应用在 Android 设备上的外观、交互和用户体验保持一致。以下是一些常见的 Android App 设计规范要点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开…

leetcode739. 每日温度 单调栈

自己思路&#xff1a; 想到用两个栈&#xff0c;一个维护元素、另一个维护下标。但是还是无法处理有重复元素的问题&#xff08;用哈希表来存储的时候&#xff09;。所以就看了答案的思路。 答案思路&#xff1a; 从前往后遍历&#xff0c;维护一个单调栈。栈存放数组的下标。…

5G NR:RACH流程-- Msg1之生成PRACH Preamble

随机接入流程中的Msg1&#xff0c;即在PRACH信道上发送random access preamble。涉及到两个问题&#xff1a; 一个是如何产生preamble&#xff1f;一个是如何选择正确的PRACH时频资源发送所选的preamble? 一、PRACH Preamble是什么 PRACH Preamble从数学上来讲是一个长度为…

springboot定时任务:同时使用定时任务和websocket报错

背景 项目使用了websocket,实现了消息的实时推送。后来项目需要一个定时任务&#xff0c;使用org.springframework.scheduling.annotation的EnableScheduling注解来实现&#xff0c;启动项目之后报错 Bean com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration of t…

MySQL 字符集概念与原理及如何配置字符集 - 超详细图文详解

目录 一、字符集概念 1、字符&#xff08;Character&#xff09; 2、字符编码 3、字符集&#xff08;Character set&#xff09; 二、字符集原理 1、ASCII字符集 2、GB2312 3、GBK 4、GB18030 5、BIG5 6、Unicode 编码 三、字符序 四、MySQL字符集 & 字符序 …

W5100S-EVB-PICO进行UDP组播数据回环测试(九)

前言 上一章我们用我们的开发板作为UDP客户端连接服务器进行数据回环测试&#xff0c;那么本章我们进行UDP组播数据回环测试。 什么是UDP组播&#xff1f; 组播是主机间一对多的通讯模式&#xff0c; 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将…

【ArcGIS Pro二次开发】(62):复制字段

应网友需求&#xff0c;做了这么一个复制字段的小工具。 假定这样一个场景&#xff0c;手头有一个要素1&#xff0c;要素里有10个字段&#xff0c;另一个要素2&#xff0c;除了shape_area等图形字段外&#xff0c;没有其它字段。 现在的需求是&#xff0c;想把要素1中的8个字…

细说百数商务模式为什么是中小企业在低代码行业创业的最优选

低代码作为软件开发工具之一&#xff0c;可覆盖制造业、金融、医疗、房地产、零售、餐饮、航空等众多行业的不同应用场景。百数低代码作为一款一站式企业协同平台&#xff0c;深耕办公领域10余年&#xff0c;为企业信息化发展提供系统化、流程化、智能化的解决方案。 百数服务…

Android ---使用Jenkins 打包release版本不能安装或者安装后不显示APP

大家在用 Jenkins的时候&#xff0c;是不是会觉得很爽&#xff0c;因为他在用的过程中&#xff0c;是无脑的&#xff0c;毕竟一键触发&#xff01;&#xff01;&#xff01;&#xff01; 这边记录一个昨天&#xff0c;今天遇到的一个坑货问题&#xff0c;别人提交了所有代码&am…

如何理解P值?

为了更好地理解p值、显著性水平、置信水平的概念&#xff0c;先看一个例子&#xff1a; 小明和小红聚餐时打赌&#xff0c;小明说 下一把骰子掷出的数值一定大于1&#xff0c;谁输了谁买单。小红盘算着要不要和小明打赌&#xff1a; 原假设H0&#xff1a;值1&#xff1b;备择…

高等数学(上)【基础学科、极限部分】

学习【高等数学&#xff08;上&#xff09;】6小时从0基础直追满绩&#xff01;_哔哩哔哩_bilibili 高数基础 高等数学无非分为三个部分&#xff1a;极限、导数&#xff08;微分&#xff09;和积分——构成了微积分 高等数学学的就是 微积分&#xff0c;整体其实只是一个思想 …