关联规则挖掘经典算法Apriori就是挖掘频繁项目集的算法,但是在面对大规模数据时其效率很低,尤其是挖掘2,3,4频繁项目集时,其实2频繁项目集挖掘可以看作是共现问题,项目中我们发现如果把2频繁项目集当作共现问题来求解其效率较当作频繁项目集求解要高很多,下面说下我们的求解思路。
对于大规模数据,要想加快速度最直观的想法就是做数据集的划分,然后并行处理。对于共现问题,数据集划分的要求是划分之后并行处理所得的结果是完备的,也就是不能丢失2频繁项目。试验中,我们所得的结果是2频繁项目的超集。
设事务数据库为:<A E F G> <A F G> <A B E F G> <E F G>
其中<A E F G>便称为事务,假设最小支持度为3,其含义为覆盖2频繁项目的事务数量大于等于3。
结论1:支撑Apriori算法的基础是如果长度为n的项目是频繁的,那么n项目的所有子集也是频繁的。
举个例子,比如在上面的事务数据集中,<A F G>是频繁项目,那么<A F G>的子集<A>,<F>,<G>,<A F>,<A G>,<F G>便都是频繁项目。
基于上面的结论,我们可以缩减计算的规模,实际操作时,可以先对原始数据集计算1频繁项目,并且按照项目的出现计数降序排列,然后对原始事务数据集进行裁剪,将原始数据集中的每一个事务投影到有序的1频繁项目集合中,并用投影结果替换事务数据集中的原始事务。
上面的事务数据库中,所有1频繁项目降序排列为(F,G,A,E),原始事务数据集做投影变成如下
<F G A E>
<F G A>
<F G A E>
<F G E>
有两点变化
一是事务数据集中所有的B被过滤掉了。
二是事务数据集中的每一个事务被按照(F,G,A,E)的顺序排序。
上面的裁剪是数据集划分的第一步,其意义在于缩减了原始事务数据集的规模,第二步是划分。
试想一下这个问题,如果要挖掘所有包含A的频繁项目集,是否需要对原始事务数据库进行处理?
答案是否,因为包含A的频繁项目集只需要处理原始事务数据集的一个子集,该子集是原始事务数据集中所有包含A的事务构成的。
对每一个1频繁项目,构造一个原始事务集的子集,该子集是原始事务数据集中所有包含此1频繁项目的事务构成的。
按照上面的思路,我们便得到下面的几个划分:
F{<F G A E>,<F G A>,<F G A E>,<F G E>}
G{<F G A E>,<F G A>,<F G A E>,<F G E>}
A{<F G A E>,<F G A>,<F G A E>}
E{<F G A E>,<F G A E>,<F G E>}
对于划分F{<F G A E>,<F G A>,<F G A E>,<F G E>},我们在做2频繁项目挖掘时,只挖掘包含F的频繁项目,由于所有1频繁项目是(F,G,A,E),根据结论1我们可以构造候选的2频繁项目集,它们是<F G>,<F A>,<F E>,在划分F中G出现了4次,A出现了3次,E出现了3次,因此他们都是2频繁项目集。
在实际的处理中,上述各个划分分别计算2频繁项目集可以并行处理,按照这样的思路在做3频繁项目集计算时,可以对上述划分按照类似的思路再处理,推而广之…