第56课:关联规则挖掘:Apriori与FP-Growth
学习目标
- 理解关联规则的核心概念:掌握支持度、置信度、提升度等关键指标
- 掌握Apriori算法原理:理解频繁项集生成与规则剪枝的过程
- 了解FP-Growth算法优势:认识其相比Apriori在效率上的改进
- 能够应用关联规则解决实际问题:使用Python实现购物篮分析等场景
- 正确解读和评估关联规则结果:避免常见误读,合理评估规则质量
核心概念
什么是关联规则挖掘?
关联规则挖掘是一种无监督学习方法,用于发现数据集中变量之间的有趣关系、频繁模式和关联性。最经典的案例是购物篮分析——发现顾客购买商品之间的关联规律,比如"购买面包的顾客中有60%也会购买牛奶"。
三个关键指标
# 假设有1000条交易记录
total_transactions = 1000
# 包含商品A的记录:300条
support_A = 300 / 1000 # = 0.3
# 同时包含A和B的记录:150条
support_AB = 150 / 1000 # = 0.15
# 包含B的记录:250条
support_B = 250 / 1000 # = 0.25
-
支持度(Support):项集在所有交易中出现的频率
Support(A→B) = P(A∩B) = 包含A和B的交易数 / 总交易数- 衡量项集的普遍性,支持度低的规则可能是偶然现象
-
置信度(Confidence):规则A→B的可靠程度
Confidence(A→B) = P(B|A) = Support(A∩B) / Support(A)- 如果置信度是0.75,表示购买A的顾客中有75%会购买B
-
提升度(Lift):衡量A和B的关联强度是否超过随机预期
Lift(A→B) = Confidence(A→B) / Support(B) = P(A∩B) / [P(A)*P(B)]- Lift > 1:正相关;Lift = 1:独立;Lift < 1:负相关
两种经典算法
Apriori算法:
- 基于"频繁项集的子集也必须是频繁的"这一先验原理
- 迭代方式:先生成频繁1-项集,再生成2-项集...直到无法生成更大的频繁项集
- 优点:简单直观,易于理解
- 缺点:需要多次扫描数据库,计算成本高
FP-Growth算法:
- 使用频繁模式树(FP-tree)数据结构
- 只需两次数据库扫描:第一次统计频率,第二次构建FP-tree
- 优点:效率更高,特别适合大型数据集
- 缺点:实现相对复杂,内存消耗可能较大
代码示例
使用Apriori算法进行购物篮分析
# 导入必要的库
import pandas as pd
from mlxtend.frequent_patterns import apriori, association_rules
from mlxtend.preprocessing import TransactionEncoder
# 模拟超市购物篮数据
dataset = [
['牛奶', '面包', '黄油'],
['面包', '尿布', '啤酒', '鸡蛋'],
['牛奶', '尿布', '啤酒', '可乐'],
['面包', '牛奶', '尿布', '啤酒'],
['面包', '牛奶', '尿布', '可乐'],
['面包', '牛奶', '啤酒'],
['牛奶', '尿布', '可乐'],
['面包', '鸡蛋', '黄油'],
['牛奶', '鸡蛋', '黄油'],
['面包', '啤酒', '可乐']
]
# 将数据转换为one-hot编码格式
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
# 使用Apriori算法找出频繁项集
# min_support=0.3 表示支持度至少为30%
frequent_itemsets = apriori(df, min_support=0.3, use_colnames=True)
print("频繁项集(支持度≥0.3):")
print(frequent_itemsets.sort_values('support', ascending=False))
# 基于频繁项集生成关联规则
# metric="confidence", min_threshold=0.7 表示置信度至少70%
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.7)
print("\n关联规则(置信度≥0.7):")
print(rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']].sort_values('confidence', ascending=False))
使用FP-Growth算法提升效率
from mlxtend.frequent_patterns import fpgrowth
# 使用FP-Growth算法找出频繁项集
frequent_itemsets_fp = fpgrowth(df, min_support=0.3, use_colnames=True)
print("FP-Growth发现的频繁项集(支持度≥0.3):")
print(frequent_itemsets_fp.sort_values('support', ascending=False))
# 生成关联规则
rules_fp = association_rules(frequent_itemsets_fp, metric="confidence", min_threshold=0.7)
print("\nFP-Growth发现的关联规则(置信度≥0.7):")
print(rules_fp[['antecedents', 'consequents', 'support', 'confidence', 'lift']].sort_values('confidence', ascending=False))
真实数据示例:超市交易数据分析
import numpy as np
np.random.seed(42)
# 生成1000条交易记录,模拟真实超市数据
products = ['面包', '牛奶', '尿布', '啤酒', '可乐', '鸡蛋', '黄油', '饼干', '果汁', '零食']
n_transactions = 1000
# 创建包含不同商品组合的交易数据
transactions = []
for i in range(n_transactions):
# 基础组合:面包+牛奶概率很高
basket = ['面包', '牛奶']
# 添加其他商品(根据设定的概率)
if np.random.random() < 0.4:
basket.append('尿布')
if '尿布' in basket and np.random.random() < 0.6:
basket.append('啤酒') # 尿布和啤酒的关联
if np.random.random() < 0.3:
basket.append('鸡蛋')
if np.random.random() < 0.25:
basket.append('黄油')
if np.random.random() < 0.35:
basket.append('可乐')
# 随机添加1-2种其他商品
other_products = [p for p in products if p not in basket]
extra = np.random.choice(other_products, size=np.random.randint(1, 3), replace=False)
basket.extend(extra)
transactions.append(list(set(basket))) # 去重
print(f"生成了{len(transactions)}条交易记录")
print("示例交易记录:", transactions[:3])
# 应用关联规则挖掘
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)
# 使用较低的支持度阈值,因为真实数据中频繁项集通常较少
frequent_itemsets = fpgrowth(df, min_support=0.1, use_colnames=True)
# 生成关联规则,调整阈值以获得有意义的结果
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.5)
# 过滤并展示有实际意义的规则
meaningful_rules = rules[(rules['lift'] > 1.2) & (rules['confidence'] > 0.6)]
meaningful_rules = meaningful_rules.sort_values(['lift', 'confidence'], ascending=[False, False])
print("\n有意义的关联规则(提升度>1.2,置信度>60%):")
print(meaningful_rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']].head(10))
实践练习
练习1:基础购物篮分析
任务:分析以下超市交易数据,找出支持度≥0.4且置信度≥0.6的关联规则。
transactions = [
['苹果', '香蕉', '橙子'],
['牛奶', '面包', '黄油'],
['苹果', '牛奶'],
['香蕉', '橙子', '苹果'],
['面包', '牛奶', '香蕉'],
['苹果', '橙子'],
['牛奶', '面包'],
['香蕉', '橙子', '苹果', '牛奶']
]
要求:
- 使用Apriori算法找出频繁项集
- 生成关联规则并按置信度排序
- 找出提升度最高的规则
预期输出:应能发现苹果、香蕉、橙子之间较强的关联关系。
练习2:电商数据关联分析
任务:使用Python生成1000条电商交易记录,包含以下商品类别:
- 电子产品:手机、电脑、耳机、平板
- 生活用品:洗发水、牙膏、毛巾
- 食品:饼干、饮料、巧克力
设置合理的购买模式(如买手机常买耳机),然后进行关联规则挖掘。
要求:
- 定义3-4个合理的购买关联模式
- 使用FP-Growth算法分析
- 找出5条最有趣的关联规则,并解释其商业价值
练习3:算法对比与优化
任务:比较Apriori和FP-Growth算法在不同数据规模下的性能差异。
要求:
- 创建不同规模的数据集(100、500、1000、5000条交易)
- 比较两种算法的运行时间
- 分析支持度阈值对结果数量的影响
- 讨论在什么情况下应该选择哪种算法
常见错误
1. 参数设置不当
# 错误:支持度阈值设置过高
frequent_itemsets = apriori(df, min_support=0.9, use_colnames=True)
# 可能结果:几乎没有频繁项集,丢失重要模式
# 错误:置信度阈值设置过低
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.1)
# 可能结果:大量低质量规则,难以分析
2. 误解关联规则含义
- 错误:将"尿布→啤酒"的高置信度解读为"啤酒会导致尿布购买"
- 正确:关联规则只表示相关性,不表示因果性
- 建议:结合业务背景解释规则,进行A/B测试验证
3. 忽视规则评估指标
# 只关注置信度,忽视提升度
# 规则A→B置信度80%,但支持度(B)=80%,则提升度=1,无意义
# 正确做法:综合考虑支持度、置信度、提升度
good_rules = rules[(rules['support'] > 0.01) &
(rules['confidence'] > 0.6) &
(rules['lift'] > 1.5)]
4. 数据预处理不足
- 没有处理缺失值和异常值
- 商品名称不一致(如"可乐"和"可口可乐"被视为不同商品)
- 没有考虑购买数量(同一商品多次购买)
小结
关键要点回顾
-
关联规则三个核心指标:
- 支持度:项集出现的频率
- 置信度:规则的可靠程度
- 提升度:关联强度是否超过随机预期
-
两种主要算法对比:
- Apriori:简单直观,适合小数据集
- FP-Growth:效率高,适合大型数据集
- 选择依据:数据规模、计算资源、实现复杂度
-
实际应用建议:
- 从较高支持度开始,逐步降低以发现更多模式
- 结合业务知识解释和验证规则
- 关注提升度>1的规则,避免虚假关联
-
常见应用场景:
- 购物篮分析:商品摆放优化、捆绑销售
- 推荐系统:基于购买历史的商品推荐
- 网页浏览模式分析:优化网站结构
- 医疗诊断:症状与疾病的关联分析
算法选择指南
- 数据量<10,000条:Apriori足够,且易于理解和调试
- 数据量>10,000条:优先考虑FP-Growth
- 内存受限环境:注意FP-Growth的内存消耗
- 快速原型开发:从Apriori开始,验证后再优化
关联规则挖掘为我们提供了一种从数据中发现隐藏模式的强大工具。通过合理设置参数、正确解读结果并结合业务背景,我们可以获得有价值的洞察,支持决策制定。在下一课中,我们将学习如何使用网格搜索进行超参数调优,进一步优化我们的机器学习模型。
练习编辑器
rust
Loading...