超市购物车里的秘密:用Python手把手教你Apriori算法找商品关联(附完整代码)
超市购物车里的秘密用Python手把手教你Apriori算法找商品关联附完整代码走进超市你是否好奇为什么尿布和啤酒总是摆在一起这背后隐藏着关联规则分析的智慧。本文将带你用Python实现经典的Apriori算法从零开始挖掘购物篮数据中的商品关联规律。1. 准备工作理解Apriori算法核心概念关联规则分析是数据挖掘中的经典技术而Apriori算法则是其中最著名的实现之一。它的核心思想很简单如果某个商品组合经常一起出现那么它们之间很可能存在某种关联。关键术语解析频繁项集Frequent Itemset经常一起出现的商品组合支持度Support某个商品组合在所有交易中出现的频率置信度Confidence购买商品A后也购买商品B的概率提升度Lift商品A和商品B之间的相关性强度提示实际应用中我们通常会设置最小支持度和最小置信度阈值过滤掉不重要的规则。2. 数据准备与预处理任何数据分析项目的第一步都是准备好数据。假设我们有一个超市购物篮数据的CSV文件格式如下transaction_id,product 1,牛奶 1,面包 2,啤酒 2,尿布 3,牛奶 3,尿布 3,啤酒用pandas读取并预处理数据import pandas as pd from itertools import combinations # 读取数据 df pd.read_csv(supermarket_transactions.csv) # 将数据转换为Apriori算法需要的格式 transactions df.groupby(transaction_id)[product].apply(list).values.tolist() print(transactions[:3]) # 查看前3条交易记录常见预处理步骤处理缺失值统一商品名称大小写去除停用词如特价、促销等标签将商品ID化对于大型数据集更高效3. 实现Apriori算法核心功能Apriori算法采用逐层搜索的方法先找出所有频繁1项集然后组合生成候选2项集再筛选出频繁2项集依此类推。3.1 生成候选项集def create_candidate_itemsets(dataset, k1): 生成初始候选项集 items set() for transaction in dataset: for item in transaction: items.add(frozenset([item])) return items3.2 计算支持度def calculate_support(dataset, candidates, min_support): 计算候选项集的支持度 item_counts {} for transaction in dataset: for candidate in candidates: if candidate.issubset(transaction): item_counts[candidate] item_counts.get(candidate, 0) 1 num_transactions len(dataset) frequent_itemsets [] support_data {} for itemset, count in item_counts.items(): support count / num_transactions if support min_support: frequent_itemsets.append(itemset) support_data[itemset] support return frequent_itemsets, support_data3.3 生成更高阶候选项集def generate_next_level_itemsets(prev_itemsets, k): 生成k项候选项集 next_itemsets set() n len(prev_itemsets) for i in range(n): for j in range(i1, n): # 合并前k-2项相同的项集 itemset1 list(prev_itemsets[i]) itemset2 list(prev_itemsets[j]) if itemset1[:k-2] itemset2[:k-2]: new_itemset prev_itemsets[i] | prev_itemsets[j] next_itemsets.add(new_itemset) return next_itemsets3.4 完整Apriori算法实现def apriori(dataset, min_support0.5): 完整的Apriori算法实现 # 初始化 k 1 C1 create_candidate_itemsets(dataset) D [set(transaction) for transaction in dataset] L1, support_data calculate_support(D, C1, min_support) L [L1] # 存储所有频繁项集 k 2 # 迭代生成更高阶频繁项集 while len(L[k-2]) 0: Ck generate_next_level_itemsets(L[k-2], k) Lk, supK calculate_support(D, Ck, min_support) support_data.update(supK) L.append(Lk) k 1 return L, support_data4. 从频繁项集中挖掘关联规则找到频繁项集后我们需要从中提取有意义的关联规则。一个好的关联规则应该同时具有较高的支持度和置信度。4.1 计算规则置信度def calculate_confidence(frequent_itemset, subset, support_data): 计算规则的置信度 return support_data[frequent_itemset] / support_data[subset]4.2 生成关联规则def generate_rules(L, support_data, min_confidence0.7): 从频繁项集中生成关联规则 rules [] # 从2项集开始生成规则 for i in range(1, len(L)): for frequent_itemset in L[i]: # 生成所有可能的子集 subsets [frozenset([item]) for item in frequent_itemset] if i 1: rules_from_conseq(frequent_itemset, subsets, support_data, rules, min_confidence) else: # 对1项子集直接计算置信度 for subset in subsets: confidence calculate_confidence( frequent_itemset, subset, support_data) if confidence min_confidence: rules.append((subset, frequent_itemset - subset, confidence)) return rules def rules_from_conseq(frequent_itemset, subsets, support_data, rules, min_confidence): 递归生成更高阶规则 m len(subsets[0]) if len(frequent_itemset) m 1: # 生成更高阶子集 next_subsets generate_next_level_itemsets(subsets, m1) # 计算置信度并筛选 confident_subsets [] for subset in next_subsets: confidence calculate_confidence( frequent_itemset, subset, support_data) if confidence min_confidence: rules.append((subset, frequent_itemset - subset, confidence)) confident_subsets.append(subset) # 如果有足够多的子集满足条件继续递归 if len(confident_subsets) 1: rules_from_conseq(frequent_itemset, confident_subsets, support_data, rules, min_confidence)5. 实战分析超市购物篮数据现在让我们用真实数据来实践一下。假设我们有一个超市的购物篮数据集包含1000条交易记录。5.1 加载并分析数据# 加载数据 transactions [ [牛奶, 面包, 黄油], [啤酒, 尿布], [牛奶, 尿布, 啤酒, 可乐], [面包, 牛奶, 尿布, 啤酒], [面包, 牛奶, 尿布, 可乐] ] # 设置最小支持度和置信度 min_support 0.4 # 40%的交易中出现 min_confidence 0.7 # 70%的置信度 # 运行Apriori算法 L, support_data apriori(transactions, min_support) # 生成关联规则 rules generate_rules(L, support_data, min_confidence) # 打印结果 print(发现的关联规则) for rule in rules: antecedent, consequent, confidence rule print(f{set(antecendent)} {set(consequent)} (置信度: {confidence:.2f}))5.2 结果解读与业务建议假设我们得到以下规则{尿布} {啤酒} (置信度: 0.75){牛奶, 面包} {黄油} (置信度: 0.80)业务建议将尿布和啤酒摆放在相邻货架或同一促销区域在牛奶和面包区域设置黄油的特价展示考虑为购买牛奶和面包的顾客提供黄油优惠券5.3 性能优化技巧对于大型数据集原始Apriori算法可能效率不高。以下是一些优化方法使用更高效的数据结构如位图表示交易数据并行计算利用多核CPU或分布式计算采样技术先在小样本上测试再应用到全量数据使用FP-Growth算法Apriori的改进版本效率更高# 使用mlxtend库的FP-Growth实现 from mlxtend.frequent_patterns import fpgrowth # 先将数据转换为one-hot编码格式 encoded_transactions pd.get_dummies(pd.DataFrame(transactions).stack()).sum(level0) # 使用FP-Growth算法 frequent_itemsets fpgrowth(encoded_transactions, min_support0.4, use_colnamesTrue)6. 进阶应用与扩展Apriori算法不仅适用于零售业还可以应用于推荐系统基于用户行为模式推荐相关商品医疗诊断发现症状与疾病之间的关联网络安全识别异常行为模式网站分析优化页面布局和用户路径实际项目中的注意事项数据质量至关重要 - 确保交易数据完整准确参数调优需要业务理解 - 支持度和置信度阈值应根据实际场景调整规则解释需要领域知识 - 单纯的数据挖掘结果需要业务专家解读考虑时间因素 - 商品关联可能随季节、促销活动变化