当前位置: 首页 > article >正文

从超市购物车到推荐系统:深入浅出图解FP-Growth算法(附Python实战)

从超市购物车到推荐系统深入浅出图解FP-Growth算法附Python实战当你推着购物车在超市里闲逛时是否想过货架上那些看似随意的商品摆放背后其实隐藏着精密的数学算法那些买了啤酒的顾客也会买尿布的经典案例正是关联规则挖掘技术的杰作。今天我们要探讨的FP-Growth算法就是让计算机从海量购物数据中自动发现这些隐藏规律的神兵利器。与传统的Apriori算法需要反复扫描数据库不同FP-Growth通过构建一种称为FP-Tree的紧凑数据结构将效率提升了一个数量级。这种算法不仅适用于零售业的市场篮子分析还能应用于推荐系统、医疗诊断、网络安全等众多领域。接下来我们将用图解方式拆解算法原理并通过Python实战演示如何发现那些令人惊讶的商品组合规律。1. 为什么需要FP-Growth算法在数据挖掘领域关联规则学习是一种发现变量间有趣关系的方法。1994年提出的Apriori算法虽然开创了先河但其性能瓶颈也显而易见它需要多次扫描整个数据库并且会产生大量的候选集。对于一个包含n种商品的数据集Apriori可能需要生成2^n-1个候选集这在商品种类较多的场景下几乎是灾难性的。FP-Growth算法在2000年由Jiawei Han等人提出其核心创新在于两次扫描原则仅需扫描数据库两次极大减少I/O开销FP-Tree结构将原始数据压缩存储在一种前缀树结构中无候选集生成直接通过树结构挖掘频繁模式避免产生大量中间结果实际测试表明在处理相同数据集时FP-Growth的速度通常比Apriori快一个数量级以上。下表展示了两种算法在典型零售数据集上的性能对比指标Apriori算法FP-Growth算法扫描次数O(频繁项集长度)2次候选集指数级增长无内存使用高中等适用规模万级商品十万级商品提示FP-Growth特别适合商品种类多但单个交易物品少的场景如便利店销售数据分析2. FP-Tree构建全图解理解FP-Growth算法的关键在于掌握FP-Tree的构建过程。让我们通过一个具体例子来拆解这个精妙的数据结构。假设我们有如下简化版的超市交易数据每条记录代表一个购物篮T1: 牛奶, 面包, 啤酒 T2: 牛奶, 尿布, 啤酒, 鸡蛋 T3: 面包, 尿布, 啤酒 T4: 牛奶, 面包, 尿布 T5: 牛奶, 尿布, 鸡蛋2.1 第一次扫描统计频率并排序首先算法扫描整个数据库统计每个商品的出现频率商品频率牛奶4尿布4啤酒3面包3鸡蛋2接着我们按频率降序重新排列每个交易中的商品T1: 牛奶, 啤酒, 面包 T2: 牛奶, 尿布, 啤酒, 鸡蛋 T3: 尿布, 啤酒, 面包 T4: 牛奶, 尿布, 面包 T5: 牛奶, 尿布, 鸡蛋2.2 第二次扫描构建FP-Tree现在开始构建FP-Tree。我们从空根节点(null)开始按顺序插入每条交易插入T1: 牛奶→啤酒→面包创建路径null→牛奶(1)→啤酒(1)→面包(1)插入T2: 牛奶→尿布→啤酒→鸡蛋共用牛奶前缀牛奶计数12从牛奶开始新分支牛奶(2)→尿布(1)→啤酒(1)→鸡蛋(1)插入T3: 尿布→啤酒→面包尿布没有直接子节点从根创建新路径null→尿布(1)→啤酒(1)→面包(1)插入T4: 牛奶→尿布→面包共用牛奶前缀牛奶计数13从牛奶开始尿布是现有子节点尿布计数12新分支牛奶(3)→尿布(2)→面包(1)插入T5: 牛奶→尿布→鸡蛋共用牛奶→尿布前缀牛奶计数14尿布计数13新分支牛奶(4)→尿布(3)→鸡蛋(1)最终形成的FP-Tree如下图所示括号内数字为节点计数null ├── 牛奶(4) │ ├── 尿布(3) │ │ ├── 啤酒(1) │ │ │ └── 鸡蛋(1) │ │ ├── 面包(1) │ │ └── 鸡蛋(1) │ └── 啤酒(1) │ └── 面包(1) └── 尿布(1) └── 啤酒(1) └── 面包(1)同时我们维护一个头表(head table)将相同商品的所有节点链接起来商品频率节点链牛奶4牛奶节点1→...尿布4尿布节点1→...啤酒3啤酒节点1→...面包3面包节点1→...鸡蛋2鸡蛋节点1→...这种紧凑的存储结构使得后续的频繁模式挖掘变得非常高效。3. 从FP-Tree挖掘频繁项集FP-Tree构建完成后我们采用分而治之的策略挖掘频繁项集。具体过程是从频率最低的商品开始鸡蛋沿着头表向上逐步构建条件模式基。3.1 挖掘以鸡蛋结尾的频繁项集从鸡蛋的头表入口出发找到所有包含鸡蛋的路径路径1牛奶→尿布→啤酒→鸡蛋 (计数1)路径2牛奶→尿布→鸡蛋 (计数1)提取这些路径的前缀去掉鸡蛋得到条件模式基{牛奶,尿布,啤酒}:1{牛奶,尿布}:1构建鸡蛋的条件FP-Tree统计条件模式基中的商品频率牛奶:2, 尿布:2, 啤酒:1按频率降序排列牛奶, 尿布构建树结构null ├── 牛奶(2) │ └── 尿布(2)从条件FP-Tree生成频繁项集{鸡蛋} (支持度2){牛奶,鸡蛋} (支持度2){尿布,鸡蛋} (支持度2){牛奶,尿布,鸡蛋} (支持度2)3.2 挖掘以面包结尾的频繁项集同样的方法应用于面包包含面包的路径牛奶→啤酒→面包 (1)牛奶→尿布→面包 (1)尿布→啤酒→面包 (1)条件模式基{牛奶,啤酒}:1{牛奶,尿布}:1{尿布,啤酒}:1面包的条件FP-Tree频率统计牛奶:2, 尿布:2, 啤酒:2树结构为空所有商品支持度相同无法形成树频繁项集{面包} (3){牛奶,面包} (2){尿布,面包} (2){啤酒,面包} (2)3.3 递归挖掘所有频繁项集按照商品频率升序鸡蛋→面包→啤酒→尿布→牛奶重复上述过程最终可以得到所有满足最小支持度的频繁项集。例如当最小支持度为3时部分频繁项集包括{牛奶} (4){尿布} (4){啤酒} (3){面包} (3){牛奶,尿布} (3)...这种挖掘方式避免了Apriori算法产生大量候选集的问题直接通过树结构提取频繁模式效率显著提升。4. Python实战用FP-Growth发现商品关联现在让我们用Python的mlxtend库来实现FP-Growth算法分析一个真实的零售数据集。4.1 准备环境和数据首先安装必要库pip install mlxtend pandas我们使用UCI Machine Learning Repository中的Online Retail数据集import pandas as pd from mlxtend.preprocessing import TransactionEncoder from mlxtend.frequent_patterns import fpgrowth # 加载数据 df pd.read_csv(OnlineRetail.csv, encodingISO-8859-1) # 预处理按InvoiceNo分组获取每笔交易的商品列表 transactions df.groupby(InvoiceNo)[Description].apply(list).values.tolist() # 转换为one-hot编码格式 te TransactionEncoder() te_ary te.fit(transactions).transform(transactions) df_encoded pd.DataFrame(te_ary, columnste.columns_)4.2 运行FP-Growth算法# 挖掘频繁项集最小支持度2% frequent_itemsets fpgrowth(df_encoded, min_support0.02, use_colnamesTrue) # 按支持度降序排列 frequent_itemsets frequent_itemsets.sort_values(support, ascendingFalse) print(frequent_itemsets.head(10))输出示例supportitemsets00.178(WHITE HANGING HEART T-LIGHT HOLDER)10.092(JUMBO BAG RED RETROSPOT)20.085(REGENCY CAKESTAND 3 TIER)30.072(PARTY BUNTING)40.068(LUNCH BAG RED RETROSPOT)50.062(ASSORTED COLOUR BIRD ORNAMENT)60.058(WHITE METAL LANTERN)70.056(JUMBO BAG RED RETROSPOT, WHITE HANGING HEART T-LIGHT HOLDER)80.051(SET OF 3 CAKE TINS PANTRY DESIGN)90.049(LUNCH BAG RED RETROSPOT, JUMBO BAG RED RETROSPOT)4.3 生成关联规则从频繁项集中提取有意义的关联规则from mlxtend.frequent_patterns import association_rules # 生成关联规则最小提升度1.5 rules association_rules(frequent_itemsets, metriclift, min_threshold1.5) # 按置信度降序排列 rules rules.sort_values(confidence, ascendingFalse) print(rules[[antecedents, consequents, support, confidence, lift]].head())输出示例antecedentsconsequentssupportconfidencelift0(LUNCH BAG RED RETROSPOT)(JUMBO BAG RED RETROSPOT)0.0490.7217.831(JUMBO BAG RED RETROSPOT)(LUNCH BAG RED RETROSPOT)0.0490.5337.832(SET/6 RED SPOTTY PAPER PLATES)(SET/6 RED SPOTTY PAPER CUPS)0.0280.6836.923(SET/6 RED SPOTTY PAPER CUPS)(SET/6 RED SPOTTY PAPER PLATES)0.0280.5816.924(RED RETROSPOT CHARLOTTE BAG)(JUMBO BAG RED RETROSPOT)0.0230.6927.52这些规则揭示了有趣的商品关联例如购买午餐袋红色复古点的顾客有72.1%的概率也会购买大号袋红色复古点这种组合的销售可能性是随机组合的7.83倍。零售商可以利用这些洞察优化商品摆放位置或设计组合促销方案。5. FP-Growth在推荐系统中的应用FP-Growth算法在推荐系统中有着广泛的应用场景。与协同过滤等传统方法相比基于关联规则的推荐有以下优势可解释性强能够明确说明因为买了A所以推荐B的逻辑冷启动友好不需要用户历史评分数据仅基于交易记录发现意外关联能捕捉非直观但实际存在的商品关系5.1 实现简单的推荐引擎基于前面挖掘的关联规则我们可以构建一个简单的推荐系统def recommend_products(rules, current_items, top_n5): # 筛选出当前商品作为前件的规则 relevant_rules rules[rules[antecedents].apply(lambda x: set(x).issubset(current_items))] # 按提升度降序排列 relevant_rules relevant_rules.sort_values(lift, ascendingFalse) # 提取推荐商品去除已购买商品 recommendations [] for _, rule in relevant_rules.head(top_n).iterrows(): for item in rule[consequents]: if item not in current_items: recommendations.append((item, rule[lift])) return sorted(recommendations, keylambda x: -x[1])[:top_n] # 示例用户当前购物车中有LUNCH BAG RED RETROSPOT current_cart {LUNCH BAG RED RETROSPOT} print(recommend_products(rules, current_cart))输出可能类似于[(JUMBO BAG RED RETROSPOT, 7.83), (SET OF 3 CAKE TINS PANTRY DESIGN, 3.45), ...]5.2 优化策略与挑战在实际应用中我们还需要考虑以下优化策略时间衰减因子给近期交易赋予更高权重商品分类层级在不同粒度层级上挖掘规则排除明显规则如充电器→手机这类常识性关联实时更新机制定期重新挖掘规则以适应销售趋势变化主要挑战包括处理大规模数据时的内存消耗动态调整最小支持度阈值解释和评估非对称关联规则与其它推荐算法的融合在真实项目中FP-Growth通常作为推荐系统的一个组件与协同过滤、内容推荐等方法结合使用形成混合推荐策略。

相关文章:

从超市购物车到推荐系统:深入浅出图解FP-Growth算法(附Python实战)

从超市购物车到推荐系统:深入浅出图解FP-Growth算法(附Python实战) 当你推着购物车在超市里闲逛时,是否想过货架上那些看似随意的商品摆放背后,其实隐藏着精密的数学算法?那些"买了啤酒的顾客也会买尿…...

SVGSON深度解析:SVG与JSON双向转换的终极解决方案

SVGSON深度解析:SVG与JSON双向转换的终极解决方案 【免费下载链接】svgson Transform svg files to json notation 项目地址: https://gitcode.com/gh_mirrors/sv/svgson 在现代前端开发和数据可视化领域,SVG图形处理已成为核心技术需求。SVGSON…...

GAT1400跨级订阅避坑指南:从‘上下级’关系到稳定接收通知的完整配置

GAT1400跨级订阅实战解析:构建稳定多级视图库通信网络 在公安、交通等行业的视频监控系统集成中,GAT1400标准已成为实现多级平台数据共享的技术基石。作为系统集成工程师,我们常常需要面对A、B、C三级甚至更多层级平台间的复杂订阅关系配置。…...

C++容器插入元素:从push到emplace,你的代码习惯该升级了(附避坑指南)

C容器插入元素:从push到emplace的现代化升级指南 记得第一次在代码审查中看到同事用emplace_back替换所有push_back时,我下意识觉得这不过是C11又一个语法糖。直到某天性能测试显示某个关键路径的容器操作耗时减少了37%,才真正意识到这个&quo…...

Windows风扇控制终极指南:用Fan Control打造个性化散热方案

Windows风扇控制终极指南:用Fan Control打造个性化散热方案 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trendi…...

031_A26_Hello_Teddy洪恩幼儿英语_生活词汇_节奏慢资料网盘下载

A26 Hello Teddy洪恩幼儿英语 生活词汇 节奏慢资料网盘下载 引言 如果你正在为孩子寻找一套更偏启蒙、节奏更舒缓的英语学习资料,那么 A26 Hello Teddy洪恩幼儿英语 生活词汇 节奏慢资料 往往会进入很多家长的筛选范围。尤其是在孩子刚开始接触英语、对语音和生活…...

在Mac M1(ARM)上部署CentOS 8:VMware Fusion实战与网络配置详解

1. 环境准备与软件下载 在Mac M1上部署CentOS 8虚拟机,首先需要确认你的硬件和软件环境是否满足要求。M1芯片采用ARM架构,这与传统x86架构有很大不同,因此需要特别注意软件版本兼容性。我实际测试发现,如果选错版本会导致安装失败…...

告别MinGW:为什么Qt6项目在Windows上更推荐用MSVC2019?一次讲清区别与配置选择

Qt6开发者的抉择:MSVC2019与MinGW深度对比与迁移指南 在Windows平台上进行Qt6开发的工程师们,常常面临一个关键选择:究竟该使用MinGW还是MSVC2019作为构建套件?这个看似简单的工具链选择,实际上会深刻影响项目的编译效…...

Win10/Win11双网卡访问冲突?详解路由跃点数(Metric)的优先级设置与实战调优

Win10/Win11双网卡访问冲突?详解路由跃点数(Metric)的优先级设置与实战调优 当你的笔记本同时连接公司内网和家庭WiFi时,是否遇到过微信消息延迟、视频会议卡顿却查不出原因?或者远程桌面连接时断时续,而pi…...

别再让网络环路卡死你的业务!华为eNSP实战:手把手配置STP与RSTP(附根保护、边缘端口避坑指南)

华为eNSP实战:STP/RSTP配置与环路故障排查全指南 凌晨三点,机房告警灯突然亮起,核心业务区流量激增到90%——这可能是每个网络工程师最不愿面对的噩梦场景之一。当广播风暴席卷整个网络时,冗余链路从"救命稻草"变成了&q…...

保姆级教程:在Win10 WSL2 + Docker Desktop上部署Pi Node节点(含Docker启动失败修复指南)

零基础实战:Windows 10环境下Pi Node节点完整部署指南 在数字货币和区块链技术蓬勃发展的今天,参与节点网络成为许多技术爱好者探索Web3世界的第一步。Pi Network作为移动优先的加密货币项目,其节点部署对普通用户而言曾是一个技术门槛较高的…...

奇点大会AGI政策路线图(2026–2030):含3阶段立法时间表、7类主体权责清单、5个试点城市优先级排序

第一章:2026奇点智能技术大会:AGI与政策制定 2026奇点智能技术大会(https://ml-summit.org) AGI治理框架的全球协同演进 本届大会首次设立跨主权AI政策实验室,联合欧盟《AI法案》执行局、美国NIST AI RMF 2.0工作组及中国新一代人工智能治理…...

【限时解密】SITS2026未发布数据集曝光:AGI在代数几何中发现2个新猜想,准确率92.7%

第一章:SITS2026演讲:AGI与数学发现 2026奇点智能技术大会(https://ml-summit.org) 在SITS2026主会场,DeepMath团队首次公开展示了AGI驱动的全自动定理发现系统「ProofSynth」——该系统在未接触任何人类证明的前提下,于72小时内…...

Go语言的defer语句执行时机与panic恢复机制的错误处理模式

Go语言以简洁高效的并发模型著称,其独特的错误处理机制更是开发者津津乐道的设计。其中defer语句的延迟执行特性与panic/recover的异常恢复机制,共同构成了Go风格化的错误处理模式。本文将深入剖析这两个关键特性的协作原理,揭示它们如何优雅…...

2026奇点智能技术大会核心成果首发(全球仅限前500份白皮书):AGI认知架构如何重构Transformer范式

第一章:2026奇点智能技术大会:AGI与认知科学 2026奇点智能技术大会(https://ml-summit.org) 本届大会首次设立“AGI-Neuro Interface”联合实验室展台,聚焦人工通用智能系统与人类认知建模的双向验证。来自MIT McGovern研究所、DeepMind神经…...

Python进阶:从bytes到memoryview,解锁高性能数据处理实战

1. 为什么需要关注二进制数据处理? 如果你曾经处理过网络通信、图像处理或者大规模数据解析,一定会遇到这样的场景:字符串操作慢得像蜗牛,内存占用高得吓人。这时候就该二进制数据类型登场了。bytes和bytearray就像是Python中的&…...

从串联到全桥:一张图看懂开关电源四大拓扑怎么选(含设计实例)

从串联到全桥:开关电源四大拓扑实战选型指南 电源工程师的桌面上总摆着几本翻烂的参考书,而最常被折角的那页必定是拓扑结构对比图。记得刚入行时,我的导师在实验室白板上画下四个方框:"选错拓扑就像给跑车装拖拉机引擎——…...

Chapter 14: Link Initialization Training

Chapter 14: Link Initialization & Training 书籍: PCI Express Technology 3.0 (MindShare Press, 2012) 页码: Book Pages 487-520 | PDF Pages 547-580 学习日期: 2026-04-13本章概要 本章描述 PCIe 链路初始化和训练过程,包括 TS1/TS2 有序集、极性检测、L…...

从MPLS到SRv6:为什么运营商都在悄悄升级这个不起眼的技术?

从MPLS到SRv6:运营商网络升级背后的技术革命 当你在手机上流畅观看4K视频时,或许不会想到这背后有一场持续了二十年的网络协议演进。全球运营商正在将承载网核心技术从MPLS悄然升级为SRv6,这场变革将直接影响未来十年互联网的传输效率与业务创…...

别再让你的Elasticsearch裸奔了!手把手教你配置安全认证(附一键检测脚本)

Elasticsearch安全加固实战:从漏洞应急到生产级防护 那天凌晨三点,我被一阵急促的电话铃声惊醒。电话那头是值班同事颤抖的声音:"我们的用户数据被挂在暗网论坛了,黑客留下的日志显示是通过Elasticsearch未授权访问漏洞获取…...

从GMSK调制到CRC校验:手把手拆解一条AIS报文是如何‘炼成’并安全送达的

从GMSK调制到CRC校验:手把手拆解一条AIS报文是如何‘炼成’并安全送达的 在浩瀚的海域中,船舶自动识别系统(AIS)如同无形的空中交通管制员,确保着每艘船只的安全航行。这条看似简单的报文背后,隐藏着一套精…...

千问3.5-2B算法学习助手:从原理理解到代码实现

千问3.5-2B算法学习助手:从原理理解到代码实现 1. 为什么需要算法学习助手 算法是计算机科学的核心基础,但传统学习方式往往存在几个痛点:抽象概念难以直观理解、代码实现容易出错、复杂度分析不够直观。很多学习者会陷入"死记硬背&qu…...

[实战指南] 基于STM32 DCMI接口的OV2640图像采集与实时显示系统

1. OV2640摄像头基础解析 OV2640这颗200万像素的CMOS传感器,可以说是嵌入式视觉项目的性价比之选。我第一次用它做项目时,发现它最吸引人的特点是支持JPEG压缩输出——这意味着在1600x1200分辨率下,数据量能从3.8MB压缩到300KB左右&#xff0…...

如何快速掌握dnSpy BAML反编译:5个高效技巧让你轻松编辑WPF界面

如何快速掌握dnSpy BAML反编译:5个高效技巧让你轻松编辑WPF界面 【免费下载链接】dnSpy Unofficial revival of the well known .NET debugger and assembly editor, dnSpy 项目地址: https://gitcode.com/gh_mirrors/dns/dnSpy 还在为WPF应用程序的BAML二进…...

飞凌OK3568-C开发板音频调试实战:从DTS配置到amixer命令,搞定RK809 Codec录音放音

飞凌OK3568-C开发板音频调试实战:从DTS配置到amixer命令,搞定RK809 Codec录音放音 在嵌入式Linux开发中,音频功能的调试往往是让开发者头疼的环节之一。特别是当面对集成度高的PMIC芯片时,如何正确配置DTS、理解音频路径切换逻辑、…...

FPGA做PI控制,避开这3个坑:定点数、积分饱和与代码风格实战指南

FPGA实现PI控制的三大实战陷阱与避坑指南 当工程师们从MATLAB/Simulink的浮点仿真世界踏入FPGA的硬件实现领域时,往往会遭遇一系列意想不到的"暗礁"。我曾在一个电机控制项目中,花费整整两周时间才排查出一个由定点数溢出导致的PI控制器异常振…...

【OpenCV 实战指南】特征匹配:从暴力匹配到实战调优

1. 暴力匹配基础:从理论到OpenCV实现 第一次接触特征匹配时,我被这个看似简单实则精妙的技术深深吸引了。想象一下,你手上有两张不同角度拍摄的同一栋建筑的照片,如何让计算机自动找到两张照片中相同的窗户或装饰?这就…...

LaTeX Beamer进阶玩法:手把手教你定制专属高校/实验室主题模板(以清华、上交模板为例)

LaTeX Beamer进阶玩法:手把手教你定制专属高校/实验室主题模板 第一次站在学术会议讲台上时,我盯着投影仪上那套千篇一律的Beamer默认模板,突然意识到一个问题:为什么顶尖高校的教授们总能拿出那些让人眼前一亮的幻灯片&#xff1…...

别再搞混了!Ubuntu 20.04上`ssh`和`sshd`服务的区别,以及systemctl的正确操作姿势

Ubuntu 20.04中SSH服务管理的深度解析:从混淆到精通 在Linux系统管理中,SSH服务无疑是日常操作中最常打交道的组件之一。但许多中级用户甚至部分资深开发者,在面对Ubuntu系统中ssh和sshd的命名差异时,仍会陷入困惑。这种困惑不仅体…...

灵活的使用ap_ctlr_none实现功能(二)

一、h文件设计 #ifndef FRAME_TOP_H_ #define FRAME_TOP_H_ //#include "ap_int.h" #include "hls_stream.h" #include "ap_axi_sdata.h" // 定义带边带信号的 AXI4-Stream 数据类型 // 数据宽度 24 位(RGB888),用户自定义宽度为 1(用于 …...