一、什么是关联规则挖掘?
关联规则挖掘(Association Rule Mining)是数据挖掘中最经典、最直观的技术之一。它的目标是从海量数据中发现项与项之间隐藏的关联或联系。
最著名的例子莫过于"尿布与啤酒"的故事:超市通过分析购物篮数据,发现购买尿布的男性顾客有很大概率会同时购买啤酒。基于这条规则,超市将啤酒货架调整到尿布旁边,从而显著提升了销量。
在我们的场景中,我们分析的不是"购物篮",而是学生的"选课篮"。我们的目标是发现类似"选了《高等数学》的学生,也很可能选《线性代数》"这样的"黄金课程搭档",从而为课程推荐、智能排课等应用提供数据支持。
二、理解三大核心指标
要衡量规则的"含金量",我们需要理解三个核心的统计指标:
1. 支持度 (Support)
支持度衡量了一个"项集"(一个或多个项的组合)在所有数据中出现的频率。
- 公式: 支持度(A, B) = 同时包含A和B的交易数 / 总交易数
- 通俗解释: 有多大比例的学生同时选择了 A 课程和 B 课程?
- 作用: 这是一个"海选"指标,用于过滤掉那些出现次数极少、纯属偶然的组合。一个组合的支持度越高,说明它越流行。
2. 置信度 (Confidence)
置信度衡量了规则的可靠性,即"如果...那么..."这个推断有多大的把握。
- 公式: 置信度(A -> B) = 支持度(A, B) / 支持度(A)
- 通俗解释: 在所有选了 A 课程的学生中,有多大比例的人也选了 B 课程?
- 作用: 这是一个"精选"指标,用于衡量规则的强度。高置信度的规则意味着 A 和 B 之间有很强的关联。
3. 提升度 (Lift)
提升度衡量了"选了 A"这件事,对"选 B"的概率有多大的提升作用。
- 公式: 提升度(A -> B) = 置信度(A -> B) / (包含B的交易数 / 总交易数)
- 通俗解释: 选了 A 课程的学生,他选择 B 课程的可能性,是普通学生选择 B 课程可能性的多少倍?
- 作用: 这是判断规则是否真正有价值的关键指标。
- Lift > 1: A 和 B 是正相关关系,A 的出现促进了 B 的出现(例如"尿布与啤酒")。
- Lift = 1: A 和 B 没有关联。
- Lift < 1: A 和 B 是负相关关系,A 的出现抑制了 B 的出现(例如选了"初级班"的学生不太可能选"高级班")。
三、Apriori 算法的两步走策略
Apriori 算法是挖掘关联规则最经典的算法,它巧妙地通过一个两步走的策略来完成任务:
第一步:寻找频繁项集 (Finding Frequent Itemsets)
这是整个过程中计算量最大的一步。算法会遍历所有数据,找出所有支持度超过我们设定的最小支持度阈值 (min_support) 的项集。 这一步就像"淘金",min_support 就是筛子的网眼大小。只有足够"大块"的金子(热门组合)才能被留下来,绝大多数沙子(偶然组合)都会被过滤掉。
第二步:生成关联规则 (Generating Rules)
算法只会在上一步找到的"频繁项集"内部寻找规则。它会计算这些组合的置信度,并找出所有超过我们设定的最小置信度阈值 (min_confidence) 的规则。 这一步就像"鉴定",我们把淘出来的金块送到实验室,用更精密的仪器(置信度、提升度)来测量它们的真正价值。
四、Python mlxtend 实战演练
mlxtend 是一个实现了多种数据挖掘算法的优秀 Python 库,让我们可以非常方便地应用 Apriori 算法。
1. 数据准备:构建事务列表
算法的输入是一个"事务列表",即一个列表,其中每个子列表代表一次交易。
# 示例:学生的选课记录
transactions = [
['数学', '物理', '化学'],
['数学', '物理'],
['数学', '英语'],
['物理', '化学'],
['英语']
]
2.数据编码:转换为 One-Hot 格式
我们需要将事务列表转换成一个算法可以处理的布尔值 DataFrame。
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder()
# .fit_transform() 会学习所有课程,并转换数据
te_ary = te.fit_transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)
# df 的内容如下:
# 化学 数学 物理 英语
# 0 True True True False
# 1 False True True False
# 2 False True False True
# 3 True False True False
# 4 False False False True
3. 执行 Apriori 并生成规则
现在,我们可以执行 Apriori 的两步走策略了。
from mlxtend.frequent_patterns import apriori, association_rules
# 第一步:寻找频繁项集,设置最小支持度为 0.4 (即至少出现 2 次)
frequent_itemsets = apriori(df, min_support=0.4, use_colnames=True)
print("--- 频繁项集 ---")
print(frequent_itemsets)
# 第二步:生成关联规则,设置最小置信度为 0.6
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.6)
print("\n--- 关联规则 ---")
print(rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])
# 输出结果:
# --- 频繁项集 ---
# support itemsets
# 0 0.6 (数学)
# 1 0.6 (物理)
# 2 0.4 (化学)
# 3 0.4 (数学, 物理)
# --- 关联规则 ---
# antecedents consequents support confidence lift
# 0 (数学) (物理) 0.4 0.666667 1.111111
# 1 (物理) (数学) 0.4 0.666667 1.111111
五、 实践中的问题与调试
问题:为什么我只能得到频繁项集,但关联规则是空的?
这是我们在实践中遇到的最典型的问题。其根本原因是:没有任何一个包含两个或更多项的“组合项集”满足 min_support 的要求。
apriori 函数只能找到单个的热门课程,无法为 association_rules 函数提供生成规则所必需的“原材料”(即多项组合)。
解决方案:调参!
min_support 是一个需要根据数据集大小和特性进行调整的超参数。
- 调低 min_support:当您发现关联规则为空时,首要的调试步骤就是大幅降低 min_support 的值(例如从 0.005 降到 0.0005)。这会放宽“海选”的标准,让更多不是那么热门、但依然有意义的组合项得以进入下一轮分析,从而成功生成关联规则。
通过本文档的梳理,相信您已经对关联规则挖掘的理论、实践和调试过程有了全面而深入的理解。