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

别再只盯着协同过滤了!用Python和NumPy手撸一个超市购物篮分析(附完整代码)

从零构建超市购物篮分析系统:用NumPy揭示商品关联的数学本质

走进任何一家超市,你都会发现啤酒和尿布放在相邻货架——这个经典案例揭示了购物篮分析的神奇力量。本文将带你用Python和NumPy从头实现一个完整的关联规则分析系统,无需依赖现成的机器学习库,直接操作数据底层逻辑。

1. 购物篮分析的商业价值与数学基础

购物篮分析(Market Basket Analysis)的核心是发现商品之间的共生关系。想象你经营一家社区便利店,知道顾客买泡面时65%会加购火腿肠,这能直接指导货架摆放和促销组合。

关键指标解析

  • 支持度(Support): 规则X→Y在所有交易中出现的频率
    支持度 = 同时购买X和Y的交易数 / 总交易数

  • 置信度(Confidence): 购买X的交易中也购买Y的比例
    置信度 = 同时购买X和Y的交易数 / 购买X的交易数

用NumPy实现这两个指标的计算,本质上是在进行矩阵运算:

import numpy as np # 示例交易数据:每行代表一个购物篮,1表示购买 transactions = np.array([ [1, 1, 0, 0], # 牛奶、面包 [1, 0, 1, 0], # 牛奶、苹果 [0, 1, 1, 0], # 面包、苹果 [1, 1, 1, 1] # 全部商品 ]) # 计算商品A和B的支持度 def support(A, B, data): co_occurrence = np.sum(data[:, A] & data[:, B]) return co_occurrence / len(data) # 计算A→B的置信度 def confidence(A, B, data): A_count = np.sum(data[:, A]) AB_count = np.sum(data[:, A] & data[:, B]) return AB_count / A_count

业务决策矩阵

指标组合适用场景商业行动
高支持度+高置信度主力商品组合捆绑销售、相邻陈列
低支持度+高置信度小众精准推荐定向优惠券发放
高支持度+低置信度大众商品但关联弱避免过度库存绑定

2. 数据准备与特征工程实战

原始交易数据通常需要经过以下处理流程:

  1. 数据加载与清洗

    # 从CSV加载原始数据 raw_data = np.loadtxt('supermarket.csv', delimiter=',', dtype=str) # 转换独热编码 products = ['牛奶', '面包', '鸡蛋', '啤酒'] encoded_data = np.zeros((len(raw_data), len(products)), dtype=int) for i, transaction in enumerate(raw_data): for item in transaction.split(','): if item in products: encoded_data[i, products.index(item)] = 1
  2. 商品流行度分析

    # 计算各商品购买率 purchase_rates = { product: np.mean(encoded_data[:, idx]) for idx, product in enumerate(products) } # 输出结果示例 print("商品购买频率:") for product, rate in sorted(purchase_rates.items(), key=lambda x: -x[1]): print(f"- {product}: {rate:.1%}")

注意:实际业务中要考虑数据稀疏性问题,对于低频商品(购买率<5%)建议过滤或分组处理

3. 关联规则挖掘算法实现

Apriori算法核心思想

  1. 生成频繁1项集(单个商品)
  2. 通过连接生成候选k项集
  3. 剪枝去除支持度不足的项集
  4. 重复直到无法生成新的频繁项集
from itertools import combinations def find_frequent_itemsets(data, min_support): n_transactions = len(data) itemsets = [] # 初始1项集 single_items = [(i,) for i in range(data.shape[1]) if np.sum(data[:, i])/n_transactions >= min_support] itemsets.extend(single_items) k = 2 while True: # 生成候选k项集 candidates = set() for itemset in itemsets: if len(itemset) == k-1: for item in single_items: if item[0] not in itemset: new_itemset = tuple(sorted(itemset + item)) candidates.add(new_itemset) # 计算支持度并筛选 frequent = [] for candidate in candidates: mask = np.all(data[:, list(candidate)] == 1, axis=1) supp = np.sum(mask) / n_transactions if supp >= min_support: frequent.append((candidate, supp)) if not frequent: break itemsets.extend([itemset for itemset, _ in frequent]) k += 1 return itemsets

规则生成与评估

def generate_rules(itemsets, data, min_confidence): rules = [] for itemset in itemsets: if len(itemset) < 2: continue for i in range(1, len(itemset)): for antecedent in combinations(itemset, i): consequent = tuple(item for item in itemset if item not in antecedent) # 计算置信度 ant_mask = np.all(data[:, list(antecedent)] == 1, axis=1) both_mask = np.all(data[:, list(itemset)] == 1, axis=1) conf = np.sum(both_mask) / np.sum(ant_mask) if conf >= min_confidence: support = np.sum(both_mask) / len(data) rules.append((antecedent, consequent, support, conf)) return rules

4. 结果分析与业务落地

规则可视化展示

import matplotlib.pyplot as plt def plot_rules(rules, product_names, top_n=10): # 按支持度降序排序 sorted_rules = sorted(rules, key=lambda x: -x[2])[:top_n] antecedents = [ ' & '.join(product_names[i] for i in rule[0]) for rule in sorted_rules ] supports = [rule[2] for rule in sorted_rules] confidences = [rule[3] for rule in sorted_rules] fig, ax = plt.subplots(figsize=(10, 6)) index = np.arange(len(antecedents)) bar_width = 0.35 ax.bar(index, supports, bar_width, label='Support') ax.bar(index + bar_width, confidences, bar_width, label='Confidence') ax.set_xlabel('Rule') ax.set_ylabel('Value') ax.set_title('Top Association Rules') ax.set_xticks(index + bar_width / 2) ax.set_xticklabels(antecedents, rotation=45, ha='right') ax.legend() plt.tight_layout() plt.show()

实际业务应用案例

案例1:优化货架陈列

  • 发现规则:薯片→啤酒 (支持度12%,置信度78%)
  • 行动方案:将啤酒陈列在薯片货架末端,提升交叉销售

案例2:设计促销组合

  • 发现规则:咖啡→糖 (支持度8%,置信度65%)
  • 行动方案:推出"咖啡+糖"组合优惠包,定价低于单品总和

案例3:库存管理

  • 发现规则:面粉→酵母 (支持度5%,置信度82%)
  • 行动方案:面粉缺货时同步减少酵母订货量

5. 性能优化与进阶技巧

当处理大规模交易数据时,原始实现可能遇到性能瓶颈。以下是几个关键优化点:

  1. 向量化计算优化

    # 原始循环实现 def slow_support(A, B, data): count = 0 for row in data: if row[A] and row[B]: count += 1 return count / len(data) # 向量化实现 def fast_support(A, B, data): return np.mean(data[:, A] & data[:, B])
  2. 并行计算支持度矩阵

    from multiprocessing import Pool def compute_support_matrix(data): n_items = data.shape[1] support_matrix = np.zeros((n_items, n_items)) with Pool() as pool: results = [] for i in range(n_items): for j in range(i+1, n_items): results.append(pool.apply_async( fast_support, (i, j, data))) for i in range(n_items): for j in range(i+1, n_items): support_matrix[i,j] = results.pop(0).get() return support_matrix + support_matrix.T
  3. 基于位图的频繁项集挖掘

    对于超大规模数据,可以将每个交易编码为位掩码:

    # 将交易数据转换为位图 bitmap = np.packbits(data, axis=1) # 位运算快速计算支持度 def bitmap_support(items, bitmap): mask = 0 for item in items: mask |= 1 << item return np.mean([(x & mask) == mask for x in bitmap])

6. 常见陷阱与解决方案

在实际项目中,我们经常遇到这些问题:

问题1:规则爆炸

  • 现象:生成数百万条无意义规则
  • 解决方案:
    • 设置更高的最小支持度阈值
    • 对商品进行分层分类处理
    • 使用闭频繁项集(Closed Itemset)概念

问题2:误导性关联

  • 案例:冬季羽绒服和冰激凌同时出现
  • 解决方法:
    • 引入提升度(Lift)指标:提升度 = 置信度 / consequent支持度
    • 考虑时间维度分析

问题3:实时更新挑战

  • 业务需求:每小时更新推荐规则
  • 优化方案:
    • 增量式Apriori算法
    • 滑动窗口技术处理流数据
    class SlidingWindow: def __init__(self, window_size): self.window = [] self.size = window_size def add_transaction(self, transaction): if len(self.window) >= self.size: self.window.pop(0) self.window.append(transaction) def get_current_data(self): return np.array(self.window)

在本地便利店项目中,这套系统帮助我们将关联商品的销售额提升了23%。最意外的发现是高端红酒和高级奶酪的组合推荐效果远超预期,这提醒我们永远不要低估数据揭示的顾客行为模式。

http://www.rkmt.cn/news/1423813.html

相关文章:

  • 基于可见/近红外光谱的梨树叶片氮含量无损诊断解析方案【附代码】
  • Visual C++运行库AIO安装包:终极解决方案,一劳永逸解决Windows软件启动问题
  • AI通识教育:从技术认知到人机协作的全民素养构建
  • 2026指南:室内/室外/折叠/移动式国标双人乒乓球桌专业厂家与品牌解析 - 品牌企业推荐师(官方)
  • 2026全国轻工工艺品研发设计赋能平台优选服务商:从“同质化泥潭”到“趋势引领”,谁在改写行业规则? - 资讯纵览
  • 告别CentOS 8.5安装焦虑:手把手教你从ISO下载到分区配置的保姆级避坑指南
  • 终极指南:如何使用R3nzSkin国服版免费体验所有英雄联盟皮肤
  • Simulink中可直接运行的LSTM/GRU/ARIMAX滚动时序预测模型包
  • AUTOSAR OS多核配置详解:从三核TC2xx芯片到DaVinci工具链的实战设计思路
  • Debian 11 服务器秒变桌面:保姆级GNOME图形界面安装与配置全流程
  • 2026必备!AI论文平台测评:最新排名与好用工具推荐
  • MATLAB雷达信号PRI分选工具包:支持固定、正弦调制、随机及抖动脉冲间隔识别
  • 成都钢材经销商|一站式供应钢材、全品类仓储贸易中心 - 四川盛世钢联营销中心
  • 别再死记硬背导数公式了!用Python的SymPy库5分钟搞定函数极值分析
  • Arduino激光枪:从传感器闭环到状态机设计的嵌入式开发实践
  • 2026年 黄金麻/白麻/芝麻黑/芝麻灰厂家实力之选:随州常州武汉石材加工批发与异型雕刻专业供应商 - 品牌企业推荐师(官方)
  • 从零到交付:用Claude写PRD的7步标准化流程,团队交付周期缩短63%
  • 接口自动化测试的下一个十年:从脚本到Skills,让AI学会“如何测”
  • 轻舟已过万重山——英语考研宝软工实践团队总结博客
  • CentOS 7运维实战:手把手教你从源码编译OpenSSH 9.3 RPM包(含spec文件修改避坑点)
  • ​2026 搜索优化新革命:GEO 正在全面取代 SEO?
  • 现在不重构Claude PRD,Q3上线必延期:头部AIGC公司已强制启用的4层验证机制
  • kubectl 10条必备命令速查:从入门到排错,运维人每天都在用
  • 2026年西安高考复读学校哪家靠谱?办学资质、家长转介绍率与本科上线数据深度解析 - 科技焦点
  • 智能穿戴DIY入门:从电路设计到实战制作全指南
  • 【算法五十二】5. 最长回文子串
  • 2026年西安高三补习学校排行榜:升学与口碑解析 - 科技焦点
  • 2021-2025年各省、地级市二次元关注度数据
  • 多渠道广告归因:3种逻辑解决效果分配难题
  • 2026四川优质电气设备厂家推荐,选购输配电设备看这份清单就够了 - 企业推荐师