数据挖掘:
从存放在数据库,数据仓库或其他信息库中的大量的数据中获取有效的、新颖的、潜在有用的、最终可理解的模式的非平凡过程。
关联规则:
假设I是项的集合。给定一个交易数据库D,其中每个事务(Transaction)t是I的非空子集,即,每一个交易都与一个唯一的标识符TID(Transaction ID)对应。关联规则在D中的支持度(support)是D中事务同时包含X、Y的百分比,即概率;置信度(confidence)是包含X的事务中同时又包含Y的百分比,即条件概率。
关联规则反映的是事物与事物间的相互关联性和依存度。当两者间满足事先设定的最小支持度和置信度时,我们认为这两者间存在关联。
例:
假设日志中整理出每个游客收听到歌曲曲目如下表所示:
项的集合: I (A,B,C,D,E,F,G,H…Z)
交易数据库:D (001,002,003…007)
TID | 歌曲1 | 歌曲2 | 歌曲3 | 歌曲4 |
001 | A | B | C |
|
002 | B | C | F |
|
003 | D | F | G |
|
004 | A | B | C | Z |
005 | B | M | H |
|
006 | B | G |
|
|
007 | B |
|
|
|
每一个事务中包含多首歌曲,不同的歌曲间存多种组合方式,他们均为潜在的关联候选项。如TID001中包含3首歌曲,通过相互间的组合可以得到4中组合方式(AB,AC,BC,ABC),而对于整个数据库而言,它所包含的候选项将是一个更为庞大的量。现在的任务就是通过关联数据挖掘,发现候选项中存在关联的组合。
计算机无法分辨各种歌曲的重要性,但可以通过假设在数据库中反复被提及到的曲目,往往是用户偏爱的,从而提取出候选曲目组合。而这个组合中的歌曲,他们间相互存在的依存度的高低也会作为该组合是否具有关联的考量。
所以对于关联规则的挖掘,分为两个步骤:
首先是在整个数据库中寻找到出现次数较多的组合设为关联候选项(即达到预先设定的一个频数support_count)。比如设定support_count=2,本例中AB,BC,AC和ABC均符合这个要求,因此将他们设为候选项.其他的组合将被抛弃。
其次是寻找强关联规则,它必须满足支持度(support)和置信度(confidence),以BC为例
B与C在整个数据库中同时存在的次数占整个交易事务数的比例:
Support(B=>C) =P(B∪C)
B与C同时出现的次数占整个数据库中B出现次数的比例:
Confidence(B=>C)=p(C|B)
本例中设置support=20%,confidence=60%
ItemSet | Support % | Confidence % |
A B | 29 | 100 |
B C | 43 | 50 |
A C | 29 | 100 |
AB C | 29 | 100 |
BC confidence仅为50%,小于confidence的60%,所以该例中BC将被删除。而AB,AC和ABC符合强关联规则
但是现在出现一个问题,挖掘候选项的时候,你会发现AB,AC,BC均为ABC的子集,这里存在一个结论后面将提及到:如果一个集合为高频项,那它的子集也一定满足最低频次的要求,也为高频项。
因此,数据挖掘的结果中会有大量重复的信息,因为一个集合包含所有子集的信息,所以将子集也统计出来就没有意义,反而会大大增加计算的负担。
因而引入两个概念封闭高频项(closed frequent itemset)和全面高频项(maximal frequent itemset)。
封闭高频项:对于itemset X不存在super-itemset y(x为y的真子集),且y和x具有相同的Support_count
全面高频项:对于itemset X不存在super-itemset y,且y也满足min_support.
这两个概念就可以在某集合认定为高频项时,排除同为高频项的子集。
按照不同情况,关联规则可以进行分类如下:
1.基于规则中处理的变量的类别,关联规则可以分为布尔型和数值型。
布尔型关联规则处理的值都是离散的、种类化的,它显示了这些变量之间的关系;而数值型关联规则可以和多维关联或多层关联规则结合起来,对数值型字段进行处理,将其进行动态的分割,或者直接对原始的数据进行处理,当然数值型关联规则中也可以包含种类变量。
例如:性别=“女”=>喜爱歌星 =“李宇春”,是布尔型关联规则;性别=“女”=>喜爱歌星数=12,涉及的歌星数是数值类型,所以是一个数值型关联规则。
2.基于规则中数据的抽象层次,可以分为单层关联规则和多层关联规则。
在单层的关联规则中,所有的变量都没有考虑到现实的数据是具有多个不同的层次的;而在多层的关联规则中,对数据的多层性已经进行了充分的考虑。
例如:周华健 =>有没有那么一首歌,是一个细节数据上的单层关联规则;港台歌手 =>有没有那么一首歌,是一个较高层次和细节层次之间的多层关联规则。
3.基于规则中涉及到的数据的维数,关联规则可以分为单维的和多维的。
在单维的关联规则中,我们只涉及到数据的一个维,如用户购买的物品;而在多维的关联规则中,要处理的数据将会涉及多个维。换成另一句话,单维关联规则是处理单个属性中的一些关系;多维关联规则是处理各个属性之间的某些关系。
例如:有没有那么一首歌 =>朋友,这条规则只涉及到歌曲,所以为单维;性别=“女”=>喜爱歌星 =“李宇春”,这条规则就涉及到两个字段的信息,是两个维上的一条关联规则。
介绍二个经典的关联数据挖掘算法
Apriori 算法
该算法应用于单维、单层、布尔关联规则,其核心是基于两阶段频集思想的递推算法。首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。
整个算法基于一个规则(Apriori property):高频次项的所有非空子集均为高频次项。
基于这个属性,首先遍历整个数据库,对1-itemsets项出现的次数进行统计,比对最小支持度,得1-itemset中的高频项,通过这些高频项生成2-itemsets的候选项,再次扫描数据库统计2-itemsets项的出现次数,再通过比对最小支持度,得到2-itemsets的高频项组合。以此类推可以实现k-itemsets推倒k+1-itemsets。
对于该算法,最大的两个问题在于产生数量相当庞大的候选项和多次对整个数据库进行扫描。
为了对该算法进行改进,最直接的方法就是减少候选项的。如在k-itemsets生成候选项后,对于候选项中的组合X,因该能够在k-1-itemsets的高频项中找到X(k-1)项的全部子集。正如本例中的 3-itemsets的{ABC}的三个子集AB AC BC,均在2-itemsets中。可以通过这个方法排除一些候选项。
Hanjiawei的书中提及了几种方法。有兴趣可以查阅。
使用Apriori对本例做一个推导:
Step1:
Candidate itemset
ItemSet | Sup.Count |
A | 2 |
B | 6 |
C | 3 |
D | 1 |
F | 2 |
G | 2 |
H | 1 |
M | 1 |
X | 1 |
Z | 1 |
Frequent itemset
ItemSet | Sup.Count |
A | 2 |
B | 6 |
C | 3 |
F | 2 |
G | 2 |
Step2:
Candidate itemset
ItemSet | Sup.Count |
AB | 2 |
AC | 2 |
AF | 0 |
AG | 0 |
BC | 2 |
BF | 1 |
BG | 1 |
CF | 1 |
CG | 0 |
FG | 1 |
Frequent Itemset
ItemSet | Sup.Count |
AB | 2 |
AC | 2 |
BC | 2 |
Step3:
Candidate Itemset
ItemSet | Sup.Count |
ABC | 2 |
Frequent Itemset
ItemSet | Sup.Count |
ABC | 2 |
程序运行后的结果如表:
候选集:a b c d f g h m z 高频集:a b c f g 候选集:ab ac af ag bc bf bg cf cg fg 高频集:ab ac bc 候选集:abc 高频集:abc |
算法伪代码表述如下:
Input:
D: 一个事务数据库
Min_support: 2
Output:
L: frequent itemsets in D
Method:
L1=find_frequent_1-itemsets(D)
For(k=2;Lk-1 is not empty;k++){
Find_Candidate_frequent_k-itemsets;
Find_Frequent_k-itemsets;
}
Procedure: Find_Candidate_frequent_k-itemsets;
For each itemset l1 of Lk-1
For each itemset l2 of Lk-1
If (l1[1]==l2[1])&& (l1[1]==l2[1])&&…(l1[k-2]==l2[k-2])&&(l1[k-1]<l2[k-1])
C= l 1 join l 2
if c has_infrequetn_subset then delete c
else add c to Candidate_itemset
Procedure: Find_Frequent_k-itemsets;
For each transaction in D
accumulate the candidate’s support_count
get the itemset >=min_support.
FP growth算法介绍:
通过一些方法减少Apriori算法中候选项的数量确实可以提高该算法的性能。但是当数据量庞大时,数据规模依然难以忍受。当存在1万个 1-itemsets时,该算法将产生至少100万的2-itemsets。而如果要挖掘一个100-itemsets的频繁项,在整个过程中将产生至少10的30次方的候选项。所以该算法很难服务于海量数据的处理。
FP growth算法采用分而治之的方法寻找高频项,它最大的特点就是不需要产生候选项。
算法描述:将数据库中的信息压缩在一个叫FP Tree的数据结构当中,该结构包含了所有itemsets间的关联信息。通过划分FP Tree为一组条件数据库(一种特殊类型的投影数据库),每个条件数据库关联一个频繁项集。
FP Tree的结构:
(1)频繁模式树(Frequent Pattern tree)简称为FP-tree,是满足下列条件的一个树结构:它由一个根节点(值为null)、项前缀子树(作为子女)和一个频繁项头表组成。
(2)项前缀子树中的每个结点包括三个域:item_name、count和node_link,其中:
item_name记录结点表示的项的标识;
count记录到达该结点的子路径的事务数;
node_link用于连接树中相同标识的下一个结点,如果不存在相同标识下一个结点,则值为“null”。
(3)频繁项头表的表项包括一个频繁项标识域:item_name和一个指向树中具有该项标识的第一个频繁项结点的头指针:head of node_link。
FP Tree的构造:
1.如同Apriori中一样对数据库进行一次扫描,并统计出每个1-itemset的数量,并作一个排序。Min_Support依然为2,删除不满足的itemsets,整理后如下表所示:
Candidate itemset
ItemSet | Sup.Count |
B | 6 |
C | 3 |
A | 2 |
F | 2 |
G | 2 |
2.创建一个树的根节点root,设为Null。数据库中的每个事务按照上表中的顺序排列,不存在于上表中的项删除。整理后如下表所示:
TID | 曲目 |
001 | BCA |
002 | BCF |
003 | FG |
004 | BCA |
005 | B |
006 | BG |
007 | B |
对于事务001,整理后为B:1,C:1,A:1,将B连接到root,C连接到B,A连接到C,形成一条子树,这三个节点的count记为1。
对于事务002,整理后为B:1,C:1,F:1,因为已经存在B和C到达root的路径了,所以不需要另立分支,只需要对B和C节点count记为2,而在C处分出一个节点F,Count记为1.
对于事务003,整理后为F:1,G:1,因为还不存在F到达null的路径,所以另立分支,如下图所示,count均记为1.
最后通过遍历整个数据库就构造了FP Tree。
3.在这个过程中需要维护一个项头表,他记录了在构造树的过程中第一次出现该项的位置。如事务001构造过程中,B,C和A都是第一次出现,他们的位置均被该表所记录。而如果第二次出现B时,则由第一次出现的B节点中node_link来记录,并依次类推。
本例FPTree构造如下:
FPTree查找:首先从项头表中最后一项开始查找,也就是G,它处于树的最末端。我们将G设为后缀,并以G为后缀寻找到达null的前缀路径,如下表所示得到了{B:1},{F:1},但他们与G可能的组合的频次都没有达到min_support,所以没有形成高频项。但在寻找到A的时候,{B,C:2}满足min_support,所以可以产生如表所示的高频项。
可以看出最终的结果和Apriori的结果相同。
Item | 条件数据库 | 条件FP Tree | 高频项 |
G | {B:1},{F:1} | 无 | 无 |
F | {B,C:1},null | 无 | 无 |
A | {B,C:2} | {B,C:2} | {A,B:2},{A,C:2},{A,B,C:2} |
C | {B:3} | {B:3} | {B,C:3} |
FPTree不需要产生候选项,并且只需要扫描2次数据库,相比Apriori有很大的优势。但它也存在一些问题,当数据库庞大时,不可能基于整个数据库在内存中构筑如此大的FPTree。一个比较好的解决方法就是将数据库切分成若干个小数据库,进行并行处理。这些问题以后再来进行讨论。