并行与分布式系统中的并行关联规则挖掘:Apriori算法的并行化
我们先理解问题本身。关联规则挖掘是从大规模事务数据中找出频繁项集(即经常一起出现的商品组合)及其关联规则(如“买了A也常买B”)。经典的Apriori算法是一种广度优先、基于候选生成的算法,其核心是“如果一个项集是频繁的,那么它的所有子集也一定是频繁的”。在并行与分布式环境下,我们需要将大规模事务数据库划分到多个处理器(节点)上,并行地生成和统计候选集,以加速挖掘过程。
我将一步步为你拆解:
1. 问题背景与串行Apriori算法回顾
假设我们有一个事务数据库D,包含N条交易记录,每条记录是若干物品的集合。我们的目标是找出所有支持度(support)不低于最小支持度阈值min_sup的频繁项集,并从中生成置信度(confidence)不低于最小置信度阈值min_conf的强关联规则。
串行Apriori算法的主要步骤是一个迭代过程:
- 第1轮(k=1):扫描数据库,统计每个单项的出现次数,找出频繁1-项集L1。
- 第2轮(k=2):利用L1生成候选2-项集C2,扫描数据库统计C2中每个候选项集的支持度,找出频繁2-项集L2。
- 第k轮(k>1):利用Lk-1(频繁(k-1)-项集)通过连接和剪枝两步生成候选k-项集Ck,扫描数据库统计Ck的支持度,找出频繁k-项集Lk。
- 当无法生成新的候选集时,算法停止。
其中,“连接”是指将Lk-1中可连接(前k-2项相同)的项对连接生成候选;“剪枝”是指删除那些包含非频繁(k-1)-子集的候选。
2. 并行化挑战与策略
串行算法的瓶颈在于多次扫描数据库以及对巨大候选集的支持度计数。并行化目标是:
- 将数据库划分到多个处理器(节点)上,使每个节点只处理局部数据。
- 并行生成候选集,并行统计支持度,最后汇总全局结果。
主要挑战在于:
- 如何高效划分数据和计算负载。
- 如何在并行计数阶段最小化通信开销。
- 如何避免重复生成候选和重复计数。
常见的并行化策略有两种:数据并行 和 任务并行。我们将重点介绍最常用的基于数据并行的方案。
3. 基于数据划分的并行Apriori算法(Count Distribution)
这是最直观的方法。假设有P个处理器(节点),将事务数据库D水平划分成P个分片D1, D2, ..., Dp,每个节点存储一个分片。
算法在每轮迭代(对于每个k)中执行以下步骤:
步骤1:候选集生成(全局同步)
- 所有节点基于上一轮得到的全局频繁项集Lk-1,独立地使用相同的连接-剪枝算法生成相同的候选k-项集Ck。由于所有节点从相同的Lk-1出发,且算法确定,因此它们能生成完全相同的Ck,无需通信传输候选集。
步骤2:局部支持度计数(并行执行)
- 每个节点pi扫描自己的本地数据分片Di,为Ck中的每个候选计算局部出现次数(局部支持度计数)。
步骤3:全局归约求和(通信步骤)
- 所有节点将自己计算出的局部计数字段(一个向量,长度为|Ck|)进行全局归约求和(All-Reduce操作)。常用MPI_Allreduce或类似的集合通信操作。结果每个节点都得到Ck中所有候选的全局支持度计数。
步骤4:全局频繁项集筛选(并行执行)
- 每个节点使用相同的全局最小支持度阈值min_sup,独立地从Ck中筛选出全局频繁k-项集Lk。同样,因为上一步后所有节点拥有相同的全局计数,它们会得到完全相同的Lk。
步骤5:判断终止
- 如果Lk为空,则算法终止;否则,k增加1,回到步骤1。
算法特性:
- 优点:通信开销相对固定,每轮只有一次全局归约(传输大小为|Ck|的计数向量)。
- 缺点:每个节点需要存储完整的候选集Ck及其计数,内存消耗大;且每轮都需要扫描整个本地数据分片。
4. 另一种优化:候选集划分(Candidate Distribution)
为了克服Count Distribution中每个节点需处理全部候选的内存瓶颈,可采用任务并行的思想,将候选集Ck划分到不同节点上。
步骤1:候选集生成与划分
- 节点0(或通过协商)生成完整的Ck,然后将其划分成P个互不相交的子集Ck1, Ck2, ..., Ckp。可以通过哈希函数(如对项集哈希取模)实现。
步骤2:数据重新分发(可选,或使用全复制)
- 方案A(数据重分布):每个节点pi将自己的本地数据分片Di广播给所有其他节点,使得每个节点都拥有完整数据库D。这样,节点pi就可以独立地为自己分配到的候选子集Cki扫描完整数据库D进行计数。
- 方案B(候选重分布):节点pi将分配到的候选子集Cki广播给所有节点。然后,每个节点pj扫描自己的本地数据分片Dj,为所有候选子集(即整个Ck)进行局部计数,但只对自己负责的那个子集Cki的计数进行累积。之后,再通过通信汇总得到每个Cki的全局计数。
步骤3:计数与汇总
- 在每个节点处理完自己负责的候选子集计数后,进行全局归约(如Gather到主节点),汇总得到完整的全局频繁项集Lk,再广播给所有节点。
算法特性:
- 优点:每个节点只负责一部分候选,内存压力小,且可并行扫描数据。
- 缺点:通信开销巨大(需要广播整个数据库或候选集,或进行复杂的计数汇总),在实践中较少单独使用。
5. 混合策略与现代优化
实际并行框架(如Spark MLlib)通常采用混合思路:
- 在低k值时(候选集不大),采用Count Distribution,通信开销小。
- 当k增大,候选集爆炸增长时,采用基于哈希的数据局部性优化。例如,将事务和候选都通过相同的哈希函数映射到不同的分区。这样,每个节点只需要获取与本地候选相关的那部分事务数据,减少通信和内存消耗。这通常与MapReduce模型结合:
- Map阶段:读取本地事务,为每个事务中的项集(组合)生成键值对,其中“键”是候选的哈希值(或候选本身),“值”是1(用于计数)。
- Shuffle阶段:将相同键(即相同候选)的键值对发送到同一个Reducer节点。
- Reduce阶段:汇总计数,筛选出频繁项集。
6. 总结
并行化Apriori算法的核心在于:
- 数据并行:将数据库划分,并行扫描局部数据,然后通过高效的全局归约通信汇总计数。
- 负载均衡:通过哈希等方法均匀划分候选集或事务数据。
- 减少通信:尽量在局部完成尽可能多的工作,只交换必要的聚合信息(如计数值),而非整个数据集。
最终,通过并行化,我们能够处理单机无法容纳的海量事务数据,显著缩短关联规则挖掘的时间,这对于零售、推荐、生物信息学等领域的海量数据分析至关重要。