【营销策略算法】关联规则学习-购物篮分析
Apriori算法是关联规则学习领域中最经典、最著名的算法之一,用于从大规模数据集中发现有价值的关联规则。最典型的例子就是购物篮分析,通过分析顾客的购物篮,发现商品之间的关联关系,从而制定营销策略(如“买尿布的顾客经常也会买啤酒”)。
一、核心概念
在理解算法之前,需要先了解几个基本术语:
项集:一组物品的集合。例如
{牛奶, 面包}
就是一个包含两项的项集。支持度:一个项集出现的频率,即它占总交易次数的百分比。
公式:
Support(A) = (包含A的交易数) / (总交易数)
意义:衡量项集的普遍性。支持度低的项集可能只是偶然出现,没有太大分析价值。
置信度:在包含项集A的交易中,同时也包含项集B的概率。它衡量的是规则
A → B
的可靠性。公式:
Confidence(A → B) = Support(A ∪ B) / Support(A)
意义:如果买A的人很大概率也会买B,那么这条规则的置信度就高。
频繁项集:支持度不低于某个预先设定的最小值支持度的项集。
关联规则:形如
A → B
的规则,表示“如果A发生,那么B也可能发生”。其中A和B都是项集,且A ∩ B = ∅。
算法的目标:找到所有满足最小支持度和最小置信度的关联规则。
二、Apriori算法的原理与步骤
Apriori算法的核心思想基于一个简单但强大的先验性质,这也是它名字的由来:
Apriori性质(先验原理):如果一个项集是频繁的,那么它的所有子集也一定是频繁的。反之,如果一个项集是非频繁的,那么它的所有超集也一定是非频繁的。
这个性质非常重要,因为它大大减少了需要计算的项集数量,避免了“组合爆炸”。
算法主要分为两个步骤:
找出所有频繁项集
从频繁项集中生成强关联规则
步骤一:找出所有频繁项集
这是一个迭代的过程,称为“逐层搜索”:
扫描数据库,计算每个单项的支持度,找出所有满足最小支持度的频繁1-项集。
连接步:基于上一层的频繁项集,生成新的候选项集。
例如,由频繁1-项集
{A}
,{B}
生成候选2-项集{A, B}
。
剪枝步:利用Apriori性质,检查候选项集的所有子集是否都是频繁的。如果某个候选项集的子集不是频繁的,那么这个候选集也不可能是频繁的,可以直接剪枝掉。
扫描数据库,计算剩余候选项集的支持度,找出满足最小支持度的频繁项集。
重复步骤2-4,直到不能再产生新的频繁项集为止。
步骤二:生成强关联规则
从上面找到的每个频繁项集中,生成所有可能的关联规则,并计算它们的置信度。
对于一个频繁项集L,生成L的所有非空子集S。
对于每个子集S,形成一条规则
S → (L - S)
。计算每条规则的置信度。如果置信度满足最小置信度阈值,则保留这条规则,称为强关联规则。
三、举例说明
假设我们有一个简单的交易数据库,最小支持度为50%,最小置信度为50%。
交易ID | 购买的商品 |
---|---|
T1 | {牛奶, 面包} |
T2 | {面包, 尿布} |
T3 | {牛奶, 面包, 尿布} |
T4 | {牛奶, 尿布} |
第一步:找出频繁项集
计算所有1-项集的支持度:
{牛奶}: 出现3次 -> 支持度 3/4 = 75%
{面包}: 出现3次 -> 支持度 3/4 = 75%
{尿布}: 出现3次 -> 支持度 3/4 = 75%
所有支持度都 > 50%,所以频繁1-项集为:{牛奶}, {面包}, {尿布}
生成候选2-项集并剪枝:
连接得到候选:{牛奶,面包}, {牛奶,尿布}, {面包,尿布}
它们的所有子集(都是1-项集)都是频繁的,所以无需剪枝。
计算支持度:
{牛奶,面包}: 出现2次 (T1, T3) -> 支持度 50%
{牛奶,尿布}: 出现2次 (T3, T4) -> 支持度 50%
{面包,尿布}: 出现2次 (T2, T3) -> 支持度 50%
所有支持度都 >= 50%,所以频繁2-项集为以上三个。
生成候选3-项集并剪枝:
连接得到候选:{牛奶,面包,尿布}
检查其子集:{牛奶,面包}, {牛奶,尿布}, {面包,尿布} 都是频繁的,所以保留。
计算支持度:{牛奶,面包,尿布} 出现1次 (T3) -> 支持度 25% < 50%
因此,它不是频繁项集。
算法停止。
第二步:从频繁2-项集生成规则
以频繁项集 {牛奶, 尿布}
为例,生成所有可能的规则并计算置信度:
规则1: {牛奶} → {尿布}
置信度 = Support({牛奶,尿布}) / Support({牛奶}) = 50% / 75% ≈ 66.7% > 50% -> 强规则
规则2: {尿布} → {牛奶}
置信度 = Support({牛奶,尿布}) / Support({尿布}) = 50% / 75% ≈ 66.7% > 50% -> 强规则
同理,我们可以分析其他频繁项集,最终得到所有有价值的规则。
四、优缺点
优点:
原理简单,易于理解和实现。
适用于稀疏数据集(如购物篮数据)。
缺点:
需要多次扫描数据库,I/O负载很大,效率较低。
可能产生大量的候选集,尤其是在支持度阈值设置较低时,仍然会面临组合爆炸问题。
对海量数据集处理性能较差。
Apriori 算法因其“产生-测试”的框架和需要多次扫描数据库而存在固有的性能瓶颈。为了克服这些问题,研究人员提出了多种更高效的算法。
这些算法主要从两个方向进行优化:
减少数据库扫描次数:Apriori 需要为每个候选集扫描一次数据库,这是其主要开销。
避免产生大量的候选集:Apriori 会产生指数级增长的候选集,并进行繁琐的支持度计数。
五、其他更高效的代表性算法
1. FP-Growth(频繁模式增长)
这是最著名、最常用的 Apriori 替代方案,它彻底改变了发现频繁项集的方式。
核心思想:采用“分而治之”的策略,将数据库压缩成一棵称为 FP-tree(频繁模式树) 的高度压缩的数据结构,然后直接在树上进行挖掘,而无需生成候选集。
工作步骤:
第一次扫描数据库:构建频繁项列表,按支持度降序排序。
第二次扫描数据库:构建 FP-tree。树的每个节点包含项名和计数。路径重叠的部分会合并,计数增加,这使得FP-tree非常紧凑。
** mining FP-tree:为每个项(从支持度最低的开始)构建条件模式基(指向该节点的所有前缀路径),然后根据这些基构建条件FP-tree**。递归地挖掘条件FP-tree,直到找到所有频繁项集。
与Apriori对比的优势:
仅需两次数据库扫描。
完全不产生候选集,避免了候选集爆炸问题。
效率通常比 Apriori 高出一个数量级。
缺点:FP-tree 可能无法完全放入内存(对于海量数据集),构建和挖掘过程对实现技巧要求较高。
2. Eclat(Equivalence Class Clustering and bottom-up Lattice Traversal)
Eclat 算法采用了与 Apriori 和 FP-Growth 完全不同的数据布局。
核心思想:使用垂直数据格式。它不是记录每个事务买了什么,而是记录每个项集出现在哪些事务中(即其 TID集)。
工作步骤:
将水平格式的数据转换为垂直格式,得到每个单项的 TID 集。
通过计算两个项集 TID 集的交集来计算它们的支持度。交集中的事务数就是支持度计数。
采用深度优先搜索策略(而非 Apriori 的广度优先)来遍历项集空间,利用交集操作来探索更长的项集。
与Apriori对比的优势:
无需多次扫描数据库,所有信息都存储在 TID 集中。
计算支持度(求交集)非常快,尤其适合内存充足的情况。
深度优先搜索占用内存更少。
缺点:对于长模式或密集数据集,TID 集可能会变得非常大,消耗大量内存。
3. 其他优化与变种算法
LCG (Linear Closed itemset Generator):专注于挖掘闭频繁项集。闭频繁项集是指其直接超集都不具有相同支持度的频繁项集。这可以极大地减少需要挖掘的项集数量,而不丢失任何信息(因为所有频繁项集都可以从闭频繁项集中推导出来)。
HMine:采用一种称为 H-Struct 的超数据结构,同样旨在减少数据库扫描次数和候选集生成,在某些场景下比 FP-Growth 更高效。
基于哈希的算法:在 Apriori 的候选集生成过程中使用哈希表来快速计数和剪枝,可以一定程度优化性能。
六、总结与对比
特性 | Apriori | FP-Growth | Eclat |
---|---|---|---|
数据格式 | 水平格式(事务->项) | 水平格式,压缩为FP-tree | 垂直格式(项->TID集) |
搜索策略 | 广度优先搜索 | 分而治之 | 深度优先搜索 |
候选集 | 产生大量候选集 | 不产生候选集 | 产生候选集,但通过TID集操作 |
数据库扫描 | 每次迭代都需要扫描 | 仅需扫描两次 | 转换后无需扫描 |
主要开销 | 候选集生成与支持度计数 | FP-tree的构建与挖掘 | TID集的交集计算与存储 |
适用场景 | 教学、小数据集 | 通用、大数据集(最常用) | 内存充足、项不太多的数据集 |
结论:
对于大多数实际应用,FP-Growth 是替代 Apriori 的首选算法,因为它在大数据集上表现出的性能优势非常明显。而 Eclat 在特定类型的数据集(尤其是内存能装下 TID 集时)上也可能有极佳的表现。
因此,虽然 Apriori 是理解关联规则挖掘的“基石”,但在处理真实世界的数据时,FP-Growth 及其变体才是更高效、更实用的工业级选择。