PFP算法
产生原因:由于无论数据集规模大小,使用的频繁项集挖掘算法所占内存的使用和计算成本代价过大,因此产生了并行式FP-Growth算法,该算法将挖掘数据集的任务分配在多个计算机上,每个计算机相互独立并行的计算与通信。
FIM(频繁项集挖掘)的定义:I={a1,a2,…am}是一个项目的集合,一个事务数据库DB是I的一个子集,DB={T1,T2,…Tn},每一个Ti属于I(1<=i<=n),Ti属于一个事务。模式A(属于I)的支持度为supp(A),是这个某些事务(包含模式A)在整个DB中的个数。A是一个频繁模式且supp(A)>=ξ(ξ被定义为最小支持度阈值)。给定一个DB和ξ,这个问题就可以描述为在DB中寻找频繁模式集合,即为频繁项集挖掘问题。
FP-Growth体现了一种分治的策略。该算法需要扫描两次数据库,第一次扫描数据库时计算所有项目的频数,并按照此频数的降序排序生成一个F-List。在第二次扫描中所有数据库中的数据都被压缩为一个FP-tree。接着FP-Growth就开始挖掘这个FP-tree,即针对每一个满足supp(A)>ξ的项目递归的生成一个条件FP-tree。然后递归的挖掘这个FP-tree。所以就把寻找频繁项目集转换为递归地查找和创建树的过程。
FP-Growth算法的不足
1.存储。对于一个非常大的DB来说,其相应的FP-tree也是十分大的,以至于不能存储内存中。所以生成比较小的DB就很有必要,所以可以把DB分为比较小的DB,然后每个DB创建本地的可以被放入内存中的FP-tree;
2.分配计算。所有的FP-Growth可以被并行化,特别是递归的调用Growth();
3.通信成本。分布式FP树可能是相互依赖的,因此可能在并行执行线程之间引起频繁同步。
4.支持度阈值。阈值越大生成的树储存的就越小,相应的时间就越少;反之亦然;
改进
针对上述FP-Growth算法的不足,PFP-Growth算法进行了改进,即对计算进行分区,使每一台计算机执行一组独立的挖掘任务,这种划分消除了计算机之间的依赖性,从而消除了计算机之间的通信。
并行式FP-Growth算法流程
Step1:分割。分割DB到P台不同的电脑,每台电脑的部分数据称为分片(shard);
Algorithm 1: FP-Growth Algorithm
Procedure: FPGrowth(DB, ξ)
Defifine and clear F-List : F[];
foreach Transaction Ti in DB do
foreach Item aj in Ti do
F[ai] ++;
end
end
Sort F[];
Defifine and clear the root of FP-tree : r;
foreach T transaction Ti in DB do
Make Ti ordered according to F;
Call Construct Tree(Ti, r);
end
foreach item ai in I do
Call Growth(r, ai, ξ);
end
Step2:并行计算。使用MapReduce计算所有项目的支持度。每个Mapper计算一个分片,最后的结果存储在F-list中;
Algorithm 2: The FP-Growth Algorithm.
Procedure: Growth(r, a, ξ)
if r contains a single path Z then
foreach combination(denoted as γ) of the nodes in
Z do
Generate pattern β = γ ∪ a with support = minimum support of nodes in γ;
if β.support > ξ then
Call Output(β);
end
end
else
foreach bi in r do
Generate pattern β = bi ∪ a with support =
bi.support;
if β.support > ξ then
Call Output(β);
end
Construct β0s conditional database ;
Construct β0s conditional FP-tree T reeβ;
if T reeβ = φ then
Call Growth(T reeβ, β, ξ);
end
end
end
Step3:划分项目组。把F-list分为Q组(每组为一个G-list),每组赋予一个唯一的组ID(gid),这个过程在一个电脑上完成;
Algorithm 3: The Parallel Counting Algorithm
Procedure: Mapper(key, value=Ti)
foreach item ai in Ti do
Call Output(hai,0 10i);
end
Procedure: Reducer(key=ai, value=S(ai))
C ← 0;
foreach item 010 in Ti do
C ← C + 1;
end
Call Output(hnull, ai + Ci);
Step4:并行FP-Growth。PFP的关键的一步,其Mapper和Reducer都是不同的操作;
Mapper:产生由组分配的事务集,事先读入G-list,输出一个或者多个key-value对,其中key为gid,value为由组分配的事务集;
Reducer:每个Reducer操作一个或者多个由组分配的分片,对于一个分片这个reducer建立一个本地的FP-tree,接着递归的建立条件FP-tree并且在递归的过程中输出发现的模式组合;
Algorithm 4: The Parallel FP-Growth Algorithm
Procedure: Mapper(key, value=Ti)
Load G-List;
Generate Hash Table H from G-List;
a[] ← Split(Ti);
for j = |Ti| − 1 to 0 do
HashNum ← getHashNum(H, a[j]);
if HashNum = Null then
Delete all pairs which hash value is HashNum
in H;
Call
Output(hHashNum, a[0] + a[1] + … + a[j]i);
end
end
Procedure: Reducer(key=gid,value=DBgid)
Load G-List;
nowGroup ← G-Listgid;
LocalF P tree ← clear;
foreach Ti in DB(gid) do
Call insert − build − f p − tree(LocalF P tree, Ti);
end
foreach ai in nowGroup do
Defifine and clear a size K max heap : HP;
Call T opKF P Growth(LocalF P tree, ai, HP);
foreach vi in HP do
Call Output(hnull, vi + supp(vi)i);
end
end
Step5:聚集所有的结果;
Algorithm 5: The Aggregating Algorithm
Procedure: Mapper(key, value=v + supp(v))
foreach item ai in v do
Call Output(hai, v + supp(v)i);
end
Procedure: Reducer(key=ai, value=S(v + supp(v)))
Defifine and clear a size K max heap : HP;
foreach pattern v in v + supp(v) do
if |HP| < K then
insert v + supp(v) into HP;
else
if supp(HP[0].v) < supp(v) then
delete top element in HP;
insert v + supp(v) into HP;
end
end
end
Call Output(hnull, ai + Ci);
应用场景
实验证明,并行式FP-Growth算法实现数据量和挖掘速度呈线性关系。即数据量越大,数据挖掘速度越快,该算法适合用于数据量大的数据集。