机器学习算法(九):Apriori算法

来源:互联网 发布:js实现二维码生成 编辑:程序博客网 时间:2024/05/22 20:13

机器学习算法(九):Apriori算法

Apriori算法是一种关联分析方法,用于发现隐藏在大型数据集中有意义的联系。所发现的联系可以使用关联规则和频繁项集来表示。

一些基本概念

项集

I={i1,i2,,id}是购物篮数据所有项的集合,而T={t1,t2,,tN}是所有事务的集合。每个事务ti包含的项集都是I的子集。在关联分析中,包含0个或多个项的集合被称为项集。如果一个项集包含k个项,则称它为k-项集。空集是指不包含任何项的项集。

项集的一个重要性质是它的支持度计数,即包含特定项集的事务个数。项集X的支持度计数σ(X)可以表示为:

σ(X)=|{ti|Xti,tiT}|

关联规则

关联规则是形如XY的蕴含表达式,其中X和Y是不相交的项集。

关联规则的强度可以用它的支持度和置信度来度量。支持度确定规则可以用于给定数据集的频繁程度,而置信度确定Y在包含X的事务中出现的频繁程度。支持度s和置信度c这两种度量的形式如下:

s(XY)=σ(XY)N

c(XY)=σ(XY)σ(X)

在关联规则的发现中,支持度通常用来删去那些无意义的规则,因为支持度低的规则可能只是偶然出现。置信度度量通过规则进行推理具有的可靠性。需要注意的一点是,由关联规则作出的推论并不必然蕴含因果关系。它只表示规则的前件和后件中的项明显地同时出现。

大多数关联规则挖掘算法通常采用的一种策略是,将任务分解为如下两个子任务:

  1. 频繁项集产生:其目标是发现满足最小支持度阈值的所有项集,这些项集称作频繁项集。
  2. 规则的产生:其目标是从上一步发现的频繁项集中提取所有满足最小置信度阈值的规则。

频繁项集的产生

使用支持度对候选项集进行剪枝基于如下原理:

先验原理:如果一个项集是频繁的,则它的所有子集一定也是频繁的。

如果项集{a, b}是非频繁的,则它的所有超集一定是非频繁的。

Apriori算法的频繁项集产生部分有两个重要的特点:第一,它是一个逐层算法,即从频繁1-项集到最长的频繁项集,它每次遍历项集格中的一层;第二,它使用产生-测试策略来发现频繁项集。在每次迭代之后,新的候选项集都是由前一次发现的频繁项集产生,然后对每个候选的支持度进行计数,并与最小支持度阈值进行比较。

算法的伪代码如下:

k = 1F_k = {i | i \in I and \sigma({i}) \geq N \times minsup} // 发现所有频繁1-项集repeat    k = k + 1    C_k = apriori-gen(F_{k - 1})    for 每个事务 t \in T do        C_t = subset(C_k, t) // 识别属于t的所有候选        for 每个候选项集 c \in C_t do            \sigma(c) = \sigma(c) + 1 //支持度计数增值        end for    end for    F_k = {c | c \in C_k and \sigma(c) \geq N \times minsup} // 提取频繁k-项集until F_k = \emptysetResult = \cup F_k

候选集的产生

函数apriori-gen的过程是合并一对频繁(k-1)-项集,仅当它们的前k-2个项都相同。令A={a1,a2,,ak1}B={b1,b2,,bk1}是一对频繁(k-1)-项集,合并A和B,如果它们满足如下条件:

ai=bi(i=1,2,,k2)ak1bk1

避免产生重复的候选集的一种方法是确保每个频繁项集中的项以字典序存储。由于每个候选都由一对频繁(k-1)-项集合并而成,因此只需要附加的候选剪枝步骤来确保该候选的其余k-2个子集是频繁的。

支持度计数

下图显示了枚举事务t中所有3-项集的系统的方法。假定每个项集中的项都以递增的字典序排序,则项集可以这样枚举:先指定最小项,其后跟随较大的项。例如,给定t={1,2,3,5,6},它的所有3-项集一定以项1、2或3开始。不必构造以5或6开始的3-项集,因为事务t中只有两个项的标号大于等于5。第一层的前缀结构描述了指定包含在事务t中的3-项集的第一项的方法。确定第一项之后,第二层的前缀结构表示选择第二项的方法。最后,第三层的前缀结构显示了事务t包含的所有的3-项集。

事务t的子集

上图所示的前缀结构演示了如何系统地枚举事务所包含的项集,即通过从最左项到最右项依次指定项集的项。然而还必须确定每一个枚举的3-项集是否对应与一个候选项集,如果它与一个候选匹配,则相应候选项集的支持度计数增值。

使用hash树进行支持度计数

在Apriori算法中,候选项集划分为不同的桶,并存放在hash树中。在支持度计数期间,包含在事务中的项集也散列到相应的桶中。这种方法不是将事务中的每个项集与所有的候选项集进行比较,而是将它与同一桶内候选项集进行匹配。

树的每个内部结点都使用Hash函数h(p)=pmod3来确定应沿当前结点的哪个分支向下。例如,项1,4和7应当散列到相同的分支,因为除以3之后它们都具有相同的余数。所有的候选集都存放在Hash树的叶结点中。

考虑一个事务t={1,2,3,5,6}。为了更新候选项的支持度计数,必须这样遍历Hash树:所有包含属于事务t的候选3-项集的叶子结点至少访问一次。注意,包含在t中的候选3-项集必须以项1,2或3开始。如上图第一层前缀结构所示。项1被散列到根节点的左子结点,项2被散列到中间的子结点,而项3被散列到右子结点。在树的下一层,根据上图中第二层结构列出的第二项进行散列。例如,在根节点散列项1之后,散列事务的项2、3和5。项2和5散列到中间的子结点,而3散列到右子结点,如下图所示。继续该过程,直至到达Hash树的叶结点。存放在被访问的叶结点中的候选项集与事务进行比较,如果候选项集是该事务的子集,则增加它的支持度计数。

hash树

关联规则的产生

当由频繁项集Y产生的规则时,下面的定理对置信度度量成立:

如果规则YXX不满足置信度阈值,则形如YXX的规则一定也不满足置信度阈值,其中X是X的子集。

Apriori算法使用一种逐层方法来产生关联规则,其中每层对应于规则后件中的项数。初始,提取规则后件只含有一个项的所有高置信度规则,然后,使用这些规则来产生新的候选规则。

算法的伪代码如下:

for 每一个频繁k-项集f_k, k \geq 2 do    H_1 = {i | i \in f_k} \\规则的1-项后件    call ap-genrules(f_k, H_1)end for

函数ap-genrules的伪码如下:

k = |f_k| //频繁项集的大小m = |H_m| //规则后件的大小if k > m + 1 then    H_{m + 1} = apriori-gen(H_m)    for 每个h_{m + 1} \in H_{m + 1} do        conf = \sigma(f_k) / \sigma(f_k - h_{m + 1})        if conf \geq minconf then            output: 规则(f_k - h_{m + 1}) \rightarrow h_{m + 1}        elseH_{m + 1} delete h_{m + 1}        end if    end for    call ap-genrules(f_k, H_{m + 1})end if

该函数中的apriori-gen函数与产生频繁项集候选集的过程类似。二者不同的是,在规则产生时,不必再次扫描数据集来计算候选规则的置信度,而是使用在频繁项集产生时计算的支持度计数来确定每个规则的置信度。

写在最后

博客的部分内容源自《数据挖掘导论》一书。

0 0
原创粉丝点击