本节将会对于Apriori算法的频繁集筛选过程,进行代码的展示
1 回顾
上节提到,对于Apriori算法来说,其核心价值是在关联分析的两个过程,即筛选频繁项集、关联规则获取的过程中,使得过程更加简便。
首先,回顾一下Apriori算法中使得计算过程变得简便的原理(Apriori原理):
- 如果某个项集是频繁的,那么它的所有子集也是频繁的
- 反之,如果一个项集是非频繁集,那么 它的所有超集也是非频繁的
此原理的论证部分,已在上文的结尾证明过。因此,我们现在需要考虑的问题就是,如何从原始数据集和出发,按照自己定义的”频繁“程度,对项集进行筛选,得到频繁项集。
2 筛选候选集
2.1 理论部分讲解
我们很容易能够想到,如果需要筛选,我们必须具有一个筛选前的总体部分。即,我们应该先从初始的以记录形式存储的数据集,转化为一个一个的项集。
这里解释一下项集的意思:以购买商品为例,用户一次购物,购买的商品A,B,C,D。这条记录会以{商品A,商品B,商品C,商品D}的形式存储在数据库中,这样的一条购买记录称为一条记录(或者事务)。我们用单词缩写tran(transaction)来表示。
而这条记录的子集,例如{商品A},{商品B}等,我们称为一个项集
那么首先,我们应该获取所有的候选集。因为我们没有现成可用的数据库,因此先自己定义一个数据集合
'''
@author:小汤
编写内容:Apriori算法
'''
#函数loadDataset()
#用于返回需要寻找频繁项集的数据集合
def loadDataset():
return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]]
第二步:对于这样的一个数据集合,我们通过什么样的步骤获取其所有的组合呢?(在计算的过程中如何使用Apriori原理使得过程更加简便?)
记录 | 内容 |
---|---|
tran1 | [1,3,4] |
tran2 | [2,3,5] |
tran3 | [1,2,3,5] |
tran4 | [2,5] |
首先,对于tran1来说,我们能够抽取出来的子集应该是{1},{3},{4},然后是这三个子集的组合{1,3},{1,4},{3,4},{1,3,4}.
如果按照这一暴力方式,我们需要对每条记录都进行子集的获取,并且在获取完所有的子集后,假设以上数据集一共有n种组合方式,再对每一种组合方式(项集)进行支持度的计算。
这样的工作量是很大的。因此我们需要在生成的过程中,使用Apriori原理,对中间结果进行剪枝处理。
因此,在处理中,就可以提出了一个层的概念,如果学过数据结构的同学,对于层的概念应该会比较好理解,即类似于树的结构。对于这样的一个数据集,应该有这样的处理方式如下图:
在这个过程中,使用到的迭代的思想,先生成只有一项的项集,计算支持度,不符合要求的直接剔除(也因此剔除了它的所有父集)。循环往复,最后就可以生成符合要求的频繁集L。
接下来看代码实现部分:
2.2 主体代码部分
首先,我们根据上面的流程图,整个算法实现应该至少需要几个部分的功能函数,因此,按照流程和功能来分析就可以比较顺利的完成所有的代码:
2.2.1 创建C1层
输入:原始数据集
输出:只有一个项的项集(C1集)
逻辑:读取数据集中的每一条记录,获取其中一项,若没有记录过,就存起来,若记录过,就不存。