关联规则挖掘与Apriori算法

关联规则挖掘(Association Rule Mining)是数据挖掘中常用的一种手段,常常被运用在购物篮分析中。

1 购物篮分析

假设你是一家超市的经理,你想了解顾客的购物习惯,尤其是哪些商品是经常会被顾客同时购买?这些被挖掘出的规则可以更好的帮助超市安排商品在货架上的摆放位置,策划更吸引人的促销活动,以及向顾客进行合理的推荐等等。在开始介绍前,我们首先定义一些基本概念:

  • 所有的项(Items)的集合为\(I\)\(I=\{i_1,i_2,\dots ,i_m\}\)
  • 所有的事务(Transactions)的集合为\(T\)\(T=\{t_1,t_2,\dots ,t_n\}\)
  • 每一条事务\(t_i\)都满足\(t_i\subseteq I\)
  • 每一条事务\(t_i\)都有唯一的事务标识符\(TID\)

在超市的例子中,\(I\)即为超市销售的所有商品,\(T\)为超市的所有交易记录,一个事务数据集\(T\)可能是以下这样:

交易编号(\(TID\) 购买物品(\(t_i\))
\(1\) \(\{\)面包,芝士,牛奶\(\}\)
\(2\) \(\{\)苹果,鸡蛋,食盐,酸奶\(\}\)
\(\dots\) \(\dots\)
\(n\) \(\{\)饼干,鸡蛋,牛奶\(\}\)

2 关联规则

关联规则是形如\(X\rightarrow Y\)的蕴涵式(Implication Form),其中\(X,Y\subseteq I\)\(X\cap Y=\emptyset\)。举例说明,在超市的案例中,若有关联规则\(\{\)面包\(,\)牛奶\(\}\) \(\rightarrow\) \(\{\)鸡蛋\(\}\),则说明购买了面包和牛奶的顾客趋向于同时购买鸡蛋。在关联规则中,\(X\)\(Y\)分别称为关联规则的先导(Antecedent)和后继(Consequent)。

除此之外,例如\(X\)\(Y\)这样包含若干项(Items)的集合被称为项集(Itemset),拥有\(k\)项的项集被称作\(k\)项集(\(k\)-itemset)。例如\(\{\)面包\(,\)牛奶\(\}\)即为一个\(2\)项集。

3 支持度和置信度

支持度和置信度是度量关联规则的两种方式,对于关联规则\(X\rightarrow Y\),其在\(T\)中的支持度(Support)是指\(T\)中事务包含\(X\cup Y\)的概率:

$$Support(X\rightarrow Y)=\Pr (X\cap Y)$$

然而置信度(Confidence)是指包含\(X\)的事务中同时包含\(Y\)的概率,即

$$Confidence(X\rightarrow Y)=\Pr\left(Y|X\right)$$

为了计算支持度和置信度,我们还需要知道支持度计数这个概念。项集\(X\)的支持度计数(Support Count)是指所有事务\(T\)中包含项集\(X\)的事务的数量。假设\(T\)中一共包含\(n\)项事务,则我们有:

$$ \begin{split} Support(X\rightarrow Y)&= \frac{SupportCount(X\cap Y)}{n}\\ Confidence(X\rightarrow Y)&=\frac{SupportCount(X\cap Y)}{SupportCount(X)} \end{split} $$

事实上,关联规则是一种特殊的模式,满足当\(X\)发生时,\(Y\)有特定的概率发生。在关联规则挖掘中,我们人工设定最小支持度阈值(Minimum Support)和最小置信度阈值(Minimum Confidence),并且找出所有同时满足最小支持度阈值和最小置信度阈值的关联规则。

4 Apriori算法

挖掘关联规则一般有两个步骤:

  • 第一步:在所有项集中找出满足最小支持度(Support)阈值的所有项集,这些项集称作频繁项集(Frequent Itemset)。
  • 第二步:从上一步找到的频繁项集中提取所有高置信度(Confidence)的规则,这些规则称作强规则。

对于挖掘频繁项集(上述第一个步骤),最经典的算法便是先验算法(Apriori algorithm)。

先验算法的关键在于先验定理:如果一个项集是频繁的,则它的所有的子集一定也是频繁的;如果一个项集是非频繁的,则它的所有超集也一定是非频繁的。利用先验定理,先验算法首先扫描数据集确定每个项的支持度,从而得到所有频繁\(1\)项集\(F_1\),然后从\(k=2\)起通过频繁\(k-1\)项集\(F_{k-1}\)来产生候选\(k\)项集\(C_k\)从而达到大幅剪枝的效果。注意的是,得到\(C_k\)后还需要扫描数据集来筛选得到\(F_k\)。先验算法是一个迭代算法,\(k\)的值依次递增直至没有新的频繁项集产生。先验算法具体过程的伪代码如下:

$$ \begin{split} &AlgorithmApriori(T):\\ &\quad C_1 \leftarrow init\text{-}pass(T);\\ &\quad F1 \leftarrow \{f\mid f \in C1, f.count\ /\ n \ge MinSupport\}; \\ &\quad \textbf{for }(k=2;F_{K-1} \neq \varnothing; k++) \textbf{ do}\\ &\quad\quad C_k \leftarrow candidate\text{-}gen(F_{k-1});\\ &\quad\quad \textbf{for } t \in T \textbf{ do}\\ &\quad\quad\quad \textbf{for } c \in C_k \textbf{ do}\\ &\quad\quad\quad\quad \textbf{if } c \subseteq t \textbf{ then} \\ &\quad\quad\quad\quad\quad c.count++;\\ &\quad\quad\quad\quad \textbf{end}\\ &\quad\quad\quad \textbf{end}\\ &\quad\quad\quad F_k \leftarrow \{c \in C_k\mid c.count\ /\ n \ge MinSupport\};\\ &\quad\quad \textbf{end}\\ &\quad \textbf{return }\ F \leftarrow \bigcup_kF_k; \end{split} $$

算法中的candidate-gen函数接受\(F_{k-1}\)作为参数,并且返回一个候选\(k\)项集\(C_k\)\(C_k\)\(F_k\)的超集,而candidate-gen这个过程也可以细分为两个步骤:

  • 合并(Join Step):生成所有可能的的候选\(k\)项集
  • 剪枝(Prune Step):删除一些不可能频繁出现的候选\(k\)项集

算法具体过程如下:

$$ \begin{split} &candidate\text{-}gen(F_{k-1}):\\ &\quad C_k \leftarrow\varnothing;\\ &\quad \textbf{forall }\ f_1,f_2 \in F_{k-1} \\ &\quad\quad \text{with }\ f_1=\{i_1,\dots,i_{k-2},i_{k-1}\}\\ &\quad\quad \text{and }\ \ f_2=\{i_1,\dots,i_{k-2},i'_{k-1}\}\\ &\quad \textbf{ do}\\ &\quad\quad c \leftarrow \{i_1,\dots,i_{k-2},i_{k-1},i'_{k-1}\}; &\text{ //join step}\\ &\quad\quad C_k \leftarrow C_k \cup \{c\}\\ &\quad\quad \textbf{for } \text{each } (k-1) \text{-subset } s \text{ of } c \textbf{ do}\\ &\quad\quad\quad \textbf{if } s \notin F_{k-1}\textbf{ then} \\ &\quad\quad\quad\quad \text{delete } c \text{ from } C_k; &\text{//prune step}\\ &\quad\quad\quad\quad \textbf{break}; \\ &\quad\quad\quad \textbf{end}\\ &\quad\quad \textbf{end}\\ &\quad \textbf{return }\ C_k; \end{split} $$

我们可以发现candidate-gen中的合并和剪枝都是建立在先验定理的基础上,这可以大幅提高生成候选项集的效率使得算法具有实际应用价值。

为了更好的帮助理解,我们举例说明candidate-gen的过程。假设我们有 \(F_3 =\) \(\{\{1, 2, 3\},\) \(\{1, 2, 4\},\) \(\{1, 3, 4\},\) \(\{1, 3, 5\},\) \(\{2, 3, 4\}\}\),经过合并我们得到\(C_4 = \{\{1, 2, 3, 4\},\) \( \{1, 2, 3, 5\},\) \( \{1, 3, 4, 5\}\}\)。然后在剪枝阶段,由于\(\{1, 4, 5\} \notin F_3\),所以\(\{1, 3, 4, 5\}\)被删除,并且由于\(\{2, 3, 5\} \notin F_3\),所以\(\{1, 2, 3, 5\}\)被删除。最终我们得到候选\(4\)项集\(C_4 = \{\{1, 2, 3, 4\}\}\)。扫描数据集统计\(C_4\)\(\{1, 2, 3, 4\}\)的支持度计数即可确定\(F_4\)

5 生成关联规则

以上仅介绍了如何生成频繁项集,即先验算法的第一步。但是频繁项集不等于关联规则,所以在得到频繁项集后我们还需要进行第二步,即从频繁项集生成关联规则。该步骤非常简单直观:

  • 对于每个频繁项集\(X\),产生\(X\)的所有非空真子集
  • 对于每个非空真子集\(A\),令\(B=X-A\)
  • \(Confidence(A\rightarrow B)\) \(\ge\) \( MinConfidence\),则输出规则\(A\rightarrow B\)

6 总结

本文介绍了关联规则挖掘的基本概念,支持度和置信度的计算,以及Apriori算法。Apriori算法利用先验定理对候选项集生成的过程进行了有效的剪枝,大幅提高了计算效率,但是如何在数据量非常巨大时进行关联规则挖掘在目前依旧是一个挑战。


在手机上阅读或分享本文请扫描以下二维码:
By @Zhengyi Yang in
Tags : #association rule, #support, #confidence, #apriori algorithm,

Comments

评论功能已关闭。