用Python和NumPy从零实现商品关联规则挖掘一个超市购物篮分析的实战案例走进任何一家现代超市货架上琳琅满目的商品背后都隐藏着无数消费者行为的秘密。为什么啤酒和尿布会经常被一起购买哪些商品组合能带来更高的销售额这些问题都可以通过购物篮分析找到答案。本文将带你用Python和NumPy从零开始构建一个完整的关联规则挖掘系统无需依赖现成库直接处理原始交易数据发现那些隐藏在收银小票中的商业洞察。1. 构建模拟购物数据集在实际商业分析中我们往往无法直接获取真实的交易数据。这时生成具有统计特性的模拟数据就成为关键的第一步。让我们创建一个包含5种常见商品的模拟数据集import numpy as np # 定义商品列表 products [牛奶, 面包, 鸡蛋, 啤酒, 尿布] # 设置每种商品的独立购买概率 base_prob np.array([0.4, 0.5, 0.3, 0.2, 0.25]) # 生成1000条模拟交易记录 num_transactions 1000 data np.zeros((num_transactions, len(products)), dtypeint) # 添加商品间的关联规则啤酒→尿布 for i in range(num_transactions): for j in range(len(products)): if products[j] 啤酒 and np.random.rand() base_prob[j]*1.5: data[i,j] 1 # 如果买了啤酒增加购买尿布的概率 if np.random.rand() 0.6: data[i, products.index(尿布)] 1 elif np.random.rand() base_prob[j]: data[i,j] 1 # 保存到CSV文件 np.savetxt(market_basket.csv, data, delimiter,, fmt%d)这个模拟数据集有几个特点基础购买概率反映了商品本身的受欢迎程度专门设置了啤酒和尿布之间的强关联数据格式为0/1矩阵适合后续分析提示实际项目中你可以用pandas.read_csv()替换np.loadtxt()来处理更复杂的真实数据。2. 计算基础购买统计量在深入关联规则之前先了解一些基础统计量很有必要。这些数字能帮助我们快速把握数据全貌# 计算每种商品的总购买次数 purchase_counts np.sum(data, axis0) # 计算同时购买两种商品的次数 cooccurrence np.zeros((len(products), len(products))) for i in range(len(products)): for j in range(len(products)): cooccurrence[i,j] np.sum((data[:,i]1) (data[:,j]1)) print(各商品购买次数统计:) for product, count in zip(products, purchase_counts): print(f{product}: {count}次) print(\n商品共现矩阵:) print(cooccurrence)输出结果可能类似于各商品购买次数统计: 牛奶: 412次 面包: 498次 鸡蛋: 305次 啤酒: 308次 尿布: 352次 商品共现矩阵: [[412. 210. 125. 82. 90.] [210. 498. 155. 104. 118.] [125. 155. 305. 62. 70.] [ 82. 104. 62. 308. 186.] [ 90. 118. 70. 186. 352.]]从共现矩阵中我们已经能直观看到啤酒和尿布的组合出现频率异常高186次这提示我们可能需要进一步分析这对组合。3. 实现关联规则挖掘算法关联规则挖掘的核心是计算支持度(support)和置信度(confidence)。让我们用纯NumPy实现这些指标的计算3.1 支持度计算支持度衡量规则在所有交易中出现的频率支持度(X→Y) 同时包含X和Y的交易数 / 总交易数def calculate_support(data, item_a, item_b): 计算两个商品之间的支持度 a_and_b np.sum((data[:,item_a]1) (data[:,item_b]1)) return a_and_b / data.shape[0] # 示例计算啤酒→尿布的支持度 beer_idx products.index(啤酒) diaper_idx products.index(尿布) support calculate_support(data, beer_idx, diaper_idx) print(f啤酒→尿布的支持度: {support:.3f})3.2 置信度计算置信度衡量当X出现时Y也出现的条件概率置信度(X→Y) 同时包含X和Y的交易数 / 包含X的交易数def calculate_confidence(data, item_a, item_b): 计算从商品A到商品B的置信度 a_and_b np.sum((data[:,item_a]1) (data[:,item_b]1)) a_count np.sum(data[:,item_a]1) return a_and_b / a_count if a_count 0 else 0 # 示例计算啤酒→尿布的置信度 confidence calculate_confidence(data, beer_idx, diaper_idx) print(f啤酒→尿布的置信度: {confidence:.3f})3.3 提升度计算提升度(lift)衡量规则的有效性表示X和Y一起出现的频率是否高于随机预期提升度(X→Y) 置信度(X→Y) / 支持度(Y)def calculate_lift(data, item_a, item_b): 计算规则的提升度 conf calculate_confidence(data, item_a, item_b) supp_b np.sum(data[:,item_b]1) / data.shape[0] return conf / supp_b if supp_b 0 else 0 # 示例计算啤酒→尿布的提升度 lift calculate_lift(data, beer_idx, diaper_idx) print(f啤酒→尿布的提升度: {lift:.3f})典型输出可能如下啤酒→尿布的支持度: 0.186 啤酒→尿布的置信度: 0.604 啤酒→尿布的提升度: 1.717提升度1表示这两个商品的组合出现频率高于随机预期是值得关注的关联规则。4. 发现重要关联规则有了核心指标的计算方法我们现在可以系统地探索所有可能的商品组合找出最有价值的关联规则。4.1 生成所有可能的规则对于5种商品理论上可以生成5×420条规则不考虑同一商品的规则from collections import defaultdict def generate_all_rules(data, products): 生成所有可能的关联规则并计算指标 rules [] num_products len(products) for i in range(num_products): for j in range(num_products): if i ! j: support calculate_support(data, i, j) confidence calculate_confidence(data, i, j) lift calculate_lift(data, i, j) rules.append({ antecedent: products[i], consequent: products[j], support: support, confidence: confidence, lift: lift }) return rules all_rules generate_all_rules(data, products)4.2 筛选和排序规则通常我们会根据业务需求设置最小阈值然后按某个指标排序def filter_and_sort_rules(rules, min_support0.05, min_confidence0.3): 筛选并排序关联规则 filtered [r for r in rules if r[support] min_support and r[confidence] min_confidence] # 按提升度降序排列 return sorted(filtered, keylambda x: x[lift], reverseTrue) significant_rules filter_and_sort_rules(all_rules)4.3 可视化重要规则将结果以表格形式展示更直观前项后项支持度置信度提升度啤酒尿布0.1860.6041.717尿布啤酒0.1860.5281.717牛奶面包0.2100.5101.020面包牛奶0.2100.4221.020从表格中我们可以得出几个业务洞察啤酒和尿布确实存在强关联提升度高达1.7牛奶和面包的组合也很常见但提升度接近1可能是独立购买鸡蛋与其他商品的关联性较弱5. 从分析到商业决策关联规则的价值在于能够转化为具体的商业策略。基于我们的分析结果可以考虑以下行动商品陈列优化将啤酒和尿布放置在相邻货架或同一促销区域在啤酒冷藏柜附近增设尿布展示架捆绑销售策略设计啤酒尿布组合优惠包对同时购买这两种商品的顾客提供额外积分库存管理建议在周末啤酒销售高峰前确保尿布库存充足监控这两种商品的销售比例变化营销活动设计针对购买尿布的顾客推送啤酒优惠券在育儿类APP中投放啤酒广告注意实际应用时需要结合更多维度数据如时间、顾客属性等进行更精细化的分析。6. 扩展与优化方向基础版本实现后我们可以从多个角度提升分析系统的实用价值6.1 处理大规模数据当交易数据量很大时纯Python实现可能效率不足。我们可以利用NumPy的向量化运算优化关键计算# 向量化方式计算共现矩阵 def vectorized_cooccurrence(data): n data.shape[1] cooc np.zeros((n, n)) for i in range(n): for j in range(n): cooc[i,j] np.sum(data[:,i] data[:,j]) return cooc # 测试性能 %timeit vectorized_cooccurrence(data) # 通常比循环版本快5-10倍6.2 添加更多评估指标除了支持度、置信度和提升度还可以引入确信度(conviction): 衡量规则的反例出现频率conviction(X→Y) (1 - support(Y)) / (1 - confidence(X→Y))杠杆率(leverage): 衡量规则的实际共现与预期共现的差异leverage(X→Y) support(X→Y) - support(X)×support(Y)实现代码def calculate_conviction(data, item_a, item_b): conf calculate_confidence(data, item_a, item_b) supp_b np.sum(data[:,item_b]1) / data.shape[0] return (1 - supp_b) / (1 - conf) if conf ! 1 else float(inf) def calculate_leverage(data, item_a, item_b): supp_ab calculate_support(data, item_a, item_b) supp_a np.sum(data[:,item_a]1) / data.shape[0] supp_b np.sum(data[:,item_b]1) / data.shape[0] return supp_ab - supp_a * supp_b6.3 实时分析系统架构要将这个分析系统投入生产环境可以考虑以下架构[交易数据流] → [实时预处理] → [关联规则计算] → [结果存储] ↑ ↑ ↑ [数据采集] [特征工程] [模型更新]关键组件实现要点使用消息队列如Kafka处理实时交易数据采用微批处理方式定期更新关联规则将结果存储到Redis供推荐系统实时查询# 伪代码示例实时处理框架 class RealTimeAnalyzer: def __init__(self, window_size1000): self.window [] self.window_size window_size self.current_rules [] def add_transaction(self, items): self.window.append(items) if len(self.window) self.window_size: self.update_rules() self.window self.window[-self.window_size//2:] # 滑动窗口 def update_rules(self): data np.array(self.window) # 调用之前的分析方法 new_rules generate_all_rules(data, products) self.current_rules filter_and_sort_rules(new_rules) def get_recommendations(self, item): # 根据当前规则生成推荐 return [r for r in self.current_rules if r[antecedent] item]在实际零售场景中这种从零实现的关联规则分析系统虽然不如专业工具功能全面但它提供了完全透明的算法过程和极高的定制灵活性。通过调整各个计算环节你可以针对特定业务需求优化分析流程比如加入时间衰减因子让新交易具有更高权重或者结合商品类别信息进行分层分析。
用Python和NumPy从零实现商品关联规则挖掘:一个超市购物篮分析的实战案例
发布时间:2026/5/29 1:20:09
用Python和NumPy从零实现商品关联规则挖掘一个超市购物篮分析的实战案例走进任何一家现代超市货架上琳琅满目的商品背后都隐藏着无数消费者行为的秘密。为什么啤酒和尿布会经常被一起购买哪些商品组合能带来更高的销售额这些问题都可以通过购物篮分析找到答案。本文将带你用Python和NumPy从零开始构建一个完整的关联规则挖掘系统无需依赖现成库直接处理原始交易数据发现那些隐藏在收银小票中的商业洞察。1. 构建模拟购物数据集在实际商业分析中我们往往无法直接获取真实的交易数据。这时生成具有统计特性的模拟数据就成为关键的第一步。让我们创建一个包含5种常见商品的模拟数据集import numpy as np # 定义商品列表 products [牛奶, 面包, 鸡蛋, 啤酒, 尿布] # 设置每种商品的独立购买概率 base_prob np.array([0.4, 0.5, 0.3, 0.2, 0.25]) # 生成1000条模拟交易记录 num_transactions 1000 data np.zeros((num_transactions, len(products)), dtypeint) # 添加商品间的关联规则啤酒→尿布 for i in range(num_transactions): for j in range(len(products)): if products[j] 啤酒 and np.random.rand() base_prob[j]*1.5: data[i,j] 1 # 如果买了啤酒增加购买尿布的概率 if np.random.rand() 0.6: data[i, products.index(尿布)] 1 elif np.random.rand() base_prob[j]: data[i,j] 1 # 保存到CSV文件 np.savetxt(market_basket.csv, data, delimiter,, fmt%d)这个模拟数据集有几个特点基础购买概率反映了商品本身的受欢迎程度专门设置了啤酒和尿布之间的强关联数据格式为0/1矩阵适合后续分析提示实际项目中你可以用pandas.read_csv()替换np.loadtxt()来处理更复杂的真实数据。2. 计算基础购买统计量在深入关联规则之前先了解一些基础统计量很有必要。这些数字能帮助我们快速把握数据全貌# 计算每种商品的总购买次数 purchase_counts np.sum(data, axis0) # 计算同时购买两种商品的次数 cooccurrence np.zeros((len(products), len(products))) for i in range(len(products)): for j in range(len(products)): cooccurrence[i,j] np.sum((data[:,i]1) (data[:,j]1)) print(各商品购买次数统计:) for product, count in zip(products, purchase_counts): print(f{product}: {count}次) print(\n商品共现矩阵:) print(cooccurrence)输出结果可能类似于各商品购买次数统计: 牛奶: 412次 面包: 498次 鸡蛋: 305次 啤酒: 308次 尿布: 352次 商品共现矩阵: [[412. 210. 125. 82. 90.] [210. 498. 155. 104. 118.] [125. 155. 305. 62. 70.] [ 82. 104. 62. 308. 186.] [ 90. 118. 70. 186. 352.]]从共现矩阵中我们已经能直观看到啤酒和尿布的组合出现频率异常高186次这提示我们可能需要进一步分析这对组合。3. 实现关联规则挖掘算法关联规则挖掘的核心是计算支持度(support)和置信度(confidence)。让我们用纯NumPy实现这些指标的计算3.1 支持度计算支持度衡量规则在所有交易中出现的频率支持度(X→Y) 同时包含X和Y的交易数 / 总交易数def calculate_support(data, item_a, item_b): 计算两个商品之间的支持度 a_and_b np.sum((data[:,item_a]1) (data[:,item_b]1)) return a_and_b / data.shape[0] # 示例计算啤酒→尿布的支持度 beer_idx products.index(啤酒) diaper_idx products.index(尿布) support calculate_support(data, beer_idx, diaper_idx) print(f啤酒→尿布的支持度: {support:.3f})3.2 置信度计算置信度衡量当X出现时Y也出现的条件概率置信度(X→Y) 同时包含X和Y的交易数 / 包含X的交易数def calculate_confidence(data, item_a, item_b): 计算从商品A到商品B的置信度 a_and_b np.sum((data[:,item_a]1) (data[:,item_b]1)) a_count np.sum(data[:,item_a]1) return a_and_b / a_count if a_count 0 else 0 # 示例计算啤酒→尿布的置信度 confidence calculate_confidence(data, beer_idx, diaper_idx) print(f啤酒→尿布的置信度: {confidence:.3f})3.3 提升度计算提升度(lift)衡量规则的有效性表示X和Y一起出现的频率是否高于随机预期提升度(X→Y) 置信度(X→Y) / 支持度(Y)def calculate_lift(data, item_a, item_b): 计算规则的提升度 conf calculate_confidence(data, item_a, item_b) supp_b np.sum(data[:,item_b]1) / data.shape[0] return conf / supp_b if supp_b 0 else 0 # 示例计算啤酒→尿布的提升度 lift calculate_lift(data, beer_idx, diaper_idx) print(f啤酒→尿布的提升度: {lift:.3f})典型输出可能如下啤酒→尿布的支持度: 0.186 啤酒→尿布的置信度: 0.604 啤酒→尿布的提升度: 1.717提升度1表示这两个商品的组合出现频率高于随机预期是值得关注的关联规则。4. 发现重要关联规则有了核心指标的计算方法我们现在可以系统地探索所有可能的商品组合找出最有价值的关联规则。4.1 生成所有可能的规则对于5种商品理论上可以生成5×420条规则不考虑同一商品的规则from collections import defaultdict def generate_all_rules(data, products): 生成所有可能的关联规则并计算指标 rules [] num_products len(products) for i in range(num_products): for j in range(num_products): if i ! j: support calculate_support(data, i, j) confidence calculate_confidence(data, i, j) lift calculate_lift(data, i, j) rules.append({ antecedent: products[i], consequent: products[j], support: support, confidence: confidence, lift: lift }) return rules all_rules generate_all_rules(data, products)4.2 筛选和排序规则通常我们会根据业务需求设置最小阈值然后按某个指标排序def filter_and_sort_rules(rules, min_support0.05, min_confidence0.3): 筛选并排序关联规则 filtered [r for r in rules if r[support] min_support and r[confidence] min_confidence] # 按提升度降序排列 return sorted(filtered, keylambda x: x[lift], reverseTrue) significant_rules filter_and_sort_rules(all_rules)4.3 可视化重要规则将结果以表格形式展示更直观前项后项支持度置信度提升度啤酒尿布0.1860.6041.717尿布啤酒0.1860.5281.717牛奶面包0.2100.5101.020面包牛奶0.2100.4221.020从表格中我们可以得出几个业务洞察啤酒和尿布确实存在强关联提升度高达1.7牛奶和面包的组合也很常见但提升度接近1可能是独立购买鸡蛋与其他商品的关联性较弱5. 从分析到商业决策关联规则的价值在于能够转化为具体的商业策略。基于我们的分析结果可以考虑以下行动商品陈列优化将啤酒和尿布放置在相邻货架或同一促销区域在啤酒冷藏柜附近增设尿布展示架捆绑销售策略设计啤酒尿布组合优惠包对同时购买这两种商品的顾客提供额外积分库存管理建议在周末啤酒销售高峰前确保尿布库存充足监控这两种商品的销售比例变化营销活动设计针对购买尿布的顾客推送啤酒优惠券在育儿类APP中投放啤酒广告注意实际应用时需要结合更多维度数据如时间、顾客属性等进行更精细化的分析。6. 扩展与优化方向基础版本实现后我们可以从多个角度提升分析系统的实用价值6.1 处理大规模数据当交易数据量很大时纯Python实现可能效率不足。我们可以利用NumPy的向量化运算优化关键计算# 向量化方式计算共现矩阵 def vectorized_cooccurrence(data): n data.shape[1] cooc np.zeros((n, n)) for i in range(n): for j in range(n): cooc[i,j] np.sum(data[:,i] data[:,j]) return cooc # 测试性能 %timeit vectorized_cooccurrence(data) # 通常比循环版本快5-10倍6.2 添加更多评估指标除了支持度、置信度和提升度还可以引入确信度(conviction): 衡量规则的反例出现频率conviction(X→Y) (1 - support(Y)) / (1 - confidence(X→Y))杠杆率(leverage): 衡量规则的实际共现与预期共现的差异leverage(X→Y) support(X→Y) - support(X)×support(Y)实现代码def calculate_conviction(data, item_a, item_b): conf calculate_confidence(data, item_a, item_b) supp_b np.sum(data[:,item_b]1) / data.shape[0] return (1 - supp_b) / (1 - conf) if conf ! 1 else float(inf) def calculate_leverage(data, item_a, item_b): supp_ab calculate_support(data, item_a, item_b) supp_a np.sum(data[:,item_a]1) / data.shape[0] supp_b np.sum(data[:,item_b]1) / data.shape[0] return supp_ab - supp_a * supp_b6.3 实时分析系统架构要将这个分析系统投入生产环境可以考虑以下架构[交易数据流] → [实时预处理] → [关联规则计算] → [结果存储] ↑ ↑ ↑ [数据采集] [特征工程] [模型更新]关键组件实现要点使用消息队列如Kafka处理实时交易数据采用微批处理方式定期更新关联规则将结果存储到Redis供推荐系统实时查询# 伪代码示例实时处理框架 class RealTimeAnalyzer: def __init__(self, window_size1000): self.window [] self.window_size window_size self.current_rules [] def add_transaction(self, items): self.window.append(items) if len(self.window) self.window_size: self.update_rules() self.window self.window[-self.window_size//2:] # 滑动窗口 def update_rules(self): data np.array(self.window) # 调用之前的分析方法 new_rules generate_all_rules(data, products) self.current_rules filter_and_sort_rules(new_rules) def get_recommendations(self, item): # 根据当前规则生成推荐 return [r for r in self.current_rules if r[antecedent] item]在实际零售场景中这种从零实现的关联规则分析系统虽然不如专业工具功能全面但它提供了完全透明的算法过程和极高的定制灵活性。通过调整各个计算环节你可以针对特定业务需求优化分析流程比如加入时间衰减因子让新交易具有更高权重或者结合商品类别信息进行分层分析。