关联规则挖掘的Apriori算法改进综述

关联规则挖掘的Apriori算法改进综述
关联规则挖掘的Apriori算法改进综述

关联规则挖掘的Apriori算法改进综述

1引言

数据挖掘是一种半自动地从大量的、不完全的、有噪声的、模糊的、随机的数据中,提取出隐含在其中潜在有用的信息和知识的过程。数据挖掘从数据中提取人们感兴趣的可用信息和知识,并将提取出来的信息和知识表示成概念、规则、规律和模式。

数据挖掘,又称数据库中的知识发现(Knowledge Discovery in Database, KDD),指的是从大型数据库的数据仓库中提取人们感兴趣的知识,这些知识是隐含的、事先未知的潜在有用信息,换言之,数据挖掘是一个利用各种分析工具在海量数据中,发现模型和数据间关系的过程,这些模型和关系可以用来作出预测。对于数据挖掘技术的研究已引起了国际人工智能和数据库等领域专家与学者的广泛关注,这其中在事务数据库中挖掘关联规则是数据挖掘领域中的一个非常重要的研究课题。关联规则是美国IBM Almaden research center的Rabesh Agrawal等人于1993年首先提出的,最近几年在数据挖掘研究领域对关联规则挖掘的研究开展得比较积极和深入[1]。关联规则挖掘是发现大量数据中项集之间有趣的关联或相关关系。随着大量数据不停被地收集和存储,许多业界人士对于从数据库中挖掘关联规则越来越感兴趣。

2 Apriori算法

2.1关联规则挖掘问题的形式化描述

对于经常使用的数据,同一文件的不同版本之间的内容往往会有重复,因此数据冗余比较多,如果采用增量式压缩就可以大大节省磁盘空间。但是这样的数据是压缩的,一旦用户需要查询/恢复数据就需要解压过程,因此这会使系统性能降低。设I={i1,i2,…,im}是由m个不同的项目组成的集合,给定一个事务数据库D,其中的每一个事务T是I中一组项目的集合,即T?I,T有一个唯一的标识符TID。若项集X?I 且X?T,则事务T包含项集X。一条相联规则就是形如X?Y的蕴涵式,其中X?I,Y?I,x∩Y=Φ。相联规则X?Y成立的条件是:

(l)它具有支持度s,即事务数据库D中至少有s%的事务包含XY ∪;

(2)它具有置信度c,即在事务数据库D中包含X的事务至少有c%同时也包含Y。

关联规则的挖掘问题就是在事务数据库 D 中找出具有用户给定的最小支持度minsup 和最小置信度minconf的关联规则。

2.2 Apriori算法简介

1994 年,Rakesh AgrawalRama 和Krishnan Skrikant 首先提出了Apriori算法[2],它是一种最有影响的挖掘布尔关联规则频繁项集的算法。Apriori 算法是一种最有影响的挖掘布尔关联规则频繁项集的算法,其核心是使用候选项集找频繁项集。Apriori算法使用一种称作逐层搜索的迭代方法k-项集用于搜索以(k+l)-项集。首先,找出频繁1-项集的集合,该集合记作L1,L1 用于找频繁2-项集的集合L2,L2 从用于找L3.如此下去,直到不能找到频繁项集。

3 Apriori算法的改进

3.1 DDApriori算法[3]

从Apriori算法可以看出, 对每一Ci均对数据库扫描一次,而这时有些事务已经对频繁项集的生成不产生作用, 减少数据库 D 内不起作用的事务对于算法来说是很有必要的,本

算法的基本思想就基于此。该算法是在每次计算Ci支持记数的过程中, 给不包含Ci中的任何项集的事务打上删除标记,在以后的扫描计数中不加考虑。其实在Ci扫描过数据库后,与Ci中某一项集相同的事务t , 如果其支持记数小于Vmin sup, 这一事务对后面的频繁项集将不产生作用, 因此它也可以从数据库中删去。本算法通过增加这一事实,得出的算法比[ 3]中算法更有效。随着i 值的增大, 删除的事务也不断增大, 因而有效降低了候选项集的计数速度, 提高了整个算法的效率。

算法: DDApri ori使用根据候选生成的逐行迭代找出频繁项集

输入: 事务数据库D; 最小支持记数阈值Vmin s up

输出: D中的频繁项集L

方法:

10) L1= find frequent 1- itemsets( D) ; /

20) for( i= 2; Li- 1≠?; i + + ) {

30) Ck= aproiri _gen( Li- 1, Vmin sup) ; //产生新的候选项集, 此函数同于Apriori

算法中的函数

40) for each transaction t∈D{ //扫描D并计数

41) if t . delet e= 0 then do be gin

50) Ct= subset( Ci , t) ; //获取t的子集作为候选

51) if Ct= ?then

52) t . delet e= 1 //打上删除标志

53) els e //对每一个Ct进行计数并记录内容

54) if Ct= c then t . count + + , t . t ext= c

60) for each candi date c ∈Ct .

70) c. count + + ;

71) end

80) }

81) if 0< t. count and t. text . count< Vmin_sup then

82) t . delete= 1 //去掉已无作用的事务t

90) Li= { c∈Ci | c. c ount≥Vmin_sup} // 得到满足条件的Li

100) }

110) return L= ∪iLi ;

下面举例说明。设最小支持记数为2。支持度计数简记为Sup。图示如下:

L1

C2 database L2

从图中可以看出, 在C2 扫描数据库时, 数据库中的事务T200, T400, T500, T700 在C2 中, 且它的支持记数小于2, 因此在C3 扫描时, 数据库 D 已经不再考虑它们,数据库已经有了很大的缩小,这对于大型数据来说是很有用处的。

3.2基于矩阵的MApriori算法

本算法的基本思想为, 对数据库给出一个矩阵表示。具体方法为: 对每一成员按一序排列,事务集也按一序列进行排列。

成员分别表示行向量, 事务表示列向量,若第i 个成员在第j 个事务中,则矩阵的第i 行, 第j 列的值为1,否则为0, 称其为数据库的布尔矩阵。上面的数据库可以用矩阵表示如下:

此矩阵的行向量之和为成员出现的次数, 则一项集的支持记数可求出。对于二项集{ Ii , Ij }只需扫描第i 行与第j 行即可,他们同一列的值均为1 的个数, 即为二项集{ Ii , I j }的支持Item set

{ I1 I2}

{ I1 I3}

{ I1 I4}

{ I1 I5}

{ I2 I3}

{ I2 I4}

{ I2 I5}

{ I3 I4}

{ I3 I5}

{ I4 I5}

TID item

T100 I1 I2 I5

T200 I1 I4

T300 I3 I5

T400 I2 I4

T500 I3 I4

T600 I2 I3

T700 I4 I5

T800 I1 I2 I3 I5

T900 I1 I2 I3

Item set Sup

{ I1 I2} 3

{ I1 I3} 2

{ I1 I5} 2

{ I2 I3} 3

{ I2 I5} 2

{ I3 I5} 2

Item set

{ I1 I2 I3}

{ I1 I2 I5}

{ I2 I3 I5}

TID item

T100 I1 I2 I5

T300 I3 I5

T600 I2 I3

T800 I1 I2 I3

I5

T900 I1 I2 I3

Item set Sup

{ I1 I2 I3} 2

{ I1 I2 I5} 2

记数,依此类推。只需扫描矩阵的第i1 , i2 , , ik 行,他们同一列的值均为1 的个数即为k 项集{ Ii 1 , I i 2 , , I ik }的支持记数。可以看出, Ci扫描数据库时只扫描一部分, 而不是Apriori 算法要扫描全部数据库, 这样算法效率就高。此算法中Ci 的求法与Apriori算法一样,算法描述如下:

算法:MApri ori使用根据候选生成的逐行迭代找出频繁项集。

输入: 事务数据库D的布尔矩阵M; 最小支持记数阈值Vmin_sup.

输出: D中的频繁项集L

方法:

10) L1 = find_frequent 1- it emsets( D) ;

20) for( i= 2;Li- 1≠?; i ++ ) {

30) Ci= aproiri_gen(Li- 1 ,Vmin_sup) ; //产生新的候选项集

40) for each transaction c ?Ci{ //扫描矩阵M 并计数

50) for ( j= 1; j ≤M_列数; j ++ )

if M [ c_1] [ j] = 1 and M [ c_2] [ j] = 1 and. . . and M [ c_i] [ j] = 1 then

70) c. c ount + + ;

80) }

90) Li= { c∈Ci | c. count≥Vmin_sup} ; 得到满足条件的Li

100) }

110) return L=∪iLi;

作为理解, 取上一例子作以简单说明。由布尔矩阵的各行和可以得出一项集的支持记数,从而求出L1 , 进而得出C2。对C2 中的每一项集扫描数据库的布尔矩阵, 并且记数。比如对二项集{ I 1 , I 2 } ,只需扫描第一行与第二行, 每一列同为1 的记数,得出它的支持记数为3。依次取遍C2 , 支持记数大于或者等于Vmin_sup 的项集生成L2 , 由L 2 生成C3 ,在对C3 中的每三项集扫描布尔矩阵, 这时要扫描3 行。依此类推,直到算法终止。

3.3 基于数组的改进方法[4]

与Apr i or i算法有关的变种有很多,这些变体通常针对如下三个目标中的一个或者多个: ①最小化扫描数据的次数;②最小化必须分析的候选项集; ③最小化计算每个候选集频率所需的时间。文献[5]提出了一种基于内存数组的算法, 该算法只扫描一次数据库,建立数据库的镜像内存数组,将对数据库的扫描转化为对内存数组的扫描, 由于内存的寻址和读写速度都远远大于磁盘的寻址和读写速度, 所以该算法大大提高了Apriori算的运行速度。算法如下:

输入: Database D; Minimum support thres hold min_sup

输出: L , frequent item sets in D

方法:

L1 = Find Large Item 1( D, A[ n] [m ], min_sup) ;

L2 = Find Large Item 2( L1, A[ n] [m ] , min_sup );

L≠?; k+ + ) do begin

f or( k= 3 ;

1-k

L) ;

Ck = Apriori_gen (

1-k

f or( i= 1 ; i< = n; i++ ) do begin

C i= CandDb _gen ( Lk- 1, A [ n] [ m ], m i n_sup) ;

for all candidate c∈Ci c . count+ + ;

end

Lk = { c∈Ck | c . coun t≥min_ sup}

end

L = ∪kLk

算法分析如下:

( 1) 函数F i ndLarge Ite m1(D, A [ n] [m ], min_sup)是先扫描数据库D,对每一个事务分解成单个项目存放在二维数组A [ n ][ m ]中( n是事务个数, m 是每个事务项目数), 同时对各个项目进行统计, 找出频繁1- 项集。

( 2) 函数F i ndLarge Ite m2( L1, A [ n] [m ] , min_sup)是利用函数Apriori_gen中的joi n算法对A [ i] [ 1] , A [ i] [ 2], A [ i] [ j ]项目生成临时候选项集, 并对它们进行剪枝, 得到候选2- 项集,同时采用一个包含|L1 |*|L1 |个元素的一维数组来保存候选2- 项集在数据库中出现的次数,以便找出频繁2- 项集。

( 3) 在循环k中, 函数C andDb_g en实际上跟函数Apriori_gen的功能相似,它是将数组中的项目生成临时候选集,进行剪枝后得到候选项集, 并将对应的候选k- 项集计数器加 1 , 直到对所有数组处理完为止,找出频繁k-项集。

3.4 AprioriPro算法[7]

AprioriPro 算法是对Apriori算法的改进,通过减小数据库规模以提高算法效率,它基于以下的定理。

定理1 Ck中任一项集必是Ck-1中某一项集的超集(证明参见文献[6])。

定理2如果某一事务不包含Ck-1中的任何项集,那么删除该事务对Lj(j≥k)的计算没有影响(证明参见文献[6])。

AprioriPro算法在每次计算支持度的过程中,依据定理1和定理2,给不包含Ck 中的任何项集的事务打上删除标记,在以后的扫描计数中不加考虑,这样计算候选集支持度所涉及的记录数目将小于事务数据库中的实际记录数,并且随着k值的增大,这一差值也不断增大,因而有效降低了候选集的计数速度,提高了整个算法的效率。

3.5基于数据结构的Apriori算法[8]

由Apriori 算法的基本思想和寻找频繁项集的步骤可知,每一次产生( +1) 项集之前都必须扫描项集,而当事务集合和候选集的数据量非常巨大的时候,该算法的性能显然是非常低效的,所以就必须要对算法进行改进。

对于Apriori算法在找出所有频繁项集的过程中,每次产生频繁k 项集之前,都要对事务集合T 进行一次扫描, 而实际上事务集合中不是每个数据都对产生频繁项集有效,所以希望在扫描时去除那些对频繁项集不产生作用的数据的扫描,使得该算法的效率得到提高。不过,减少候选项集的方法上在此仍沿用上文中所述的Agrawal等引入的修剪技术。定理事务集合中所有项数小于k 的事务对于产生频繁k项集是无用的。

根据上述算法改进思想,为了进一步提高算法效率,对于事物集合存储的数据结构也可做相应的改进。可选用树型存储事物集合T,因为树结构是动态的数据结构。该树的节点结构包括该事务的长度、事务的数据和两个指针,左指针指向小于该事务长度的下一个事务,右指针指向大于事务长度的下一个事务。节点为:

这样,当开始生产频繁k-项集之前,扫描事务集合根本无需扫描小于k长度的事务子

树,因为这些事务对于频繁k-项集的生成是无用的数据。定义该树型结构的数据类型:

Typedef struct Node

{ int number; //事务项数

Trans data; //事务项内容

Struct Node *left, *right; }Node, *BiTree;

改进的Apriori 算法(事务集合T,min_sup,min_conf)

{for T 中得每个事务t

{for t 中每个项i

{i.sup_count=i.sup_count+1;}

}

}

{for 每个项 i

{if (i.sup_count>=n*min_sup)

{ L1= 1∪{i}; } /*找出频繁1_项集*/

}

}

{for (k=2; 1≠? ;k++) /*找出候选k_项集 */

{for Lk-1中的每个项集u L

{for Lk-11中的每个项集v L

{if (u L [1]= v L [1])∧…∧(u L [k-2]= v L [k-2])∧(u L [k-1]= v L [k-1])

{c=u L ∞v L ;

Ck=Ck ∪C ;

for 中的每个( k-1)-项集s /*事先剪枝*/

{if (s ? Lk-1) { Ck=Ck -s;}}

}

}

}

}

{for 扫描事务树中 number>=k 的事务 t

{for t 中的每个 k- 项子集 s

{if ( s ∈Ck ) {s.sup_count=s.sup_count+1;}}

}

}

{for Ck 中的每个项集 c/*找出频繁 k-项集*/

{if (c.sup_count>=n*min_sup) {Lk = Lk ∪c }

}

L=L ∪Lk ;

}

{for L 中的每个频繁项集 l /*求强关联规则集合*/

{for l 中的每个非空真子集

{if (l.sup_count/u L .sup_count>=min_conf)

{R_S=R_S ∪{u L =>l-u L }

}

}

}

4.结束语

Aprior 被应用于各个方面,所以也有很多相应的改进方法,例如:Web 使用挖掘中Apriori 算法的改进,改进的算法BI_Apriori [9]采用不规则的数组来保存项集信息,这些算法的主要目的都是有效省去了扫描数据库所耗费的大量时间;同时在对Apriori 算法存在的问题进行一些改进,采用新的修剪策略,利用Apriori 算法的性质找出一个影响效率的因素,用来提高算法的效率,增加独立性检验,从而将该算法能利用的更加有效。

参考文献:

[1] 冯兴杰,周谆. Apriori 算法的改进[J].计算机工程,2005,07(31):172-173

[2] 李超,余昭平. 基于矩阵的Apriori 算法改进[J].计算机工程,2006,12(32):68-69

[3]马盈仓.挖掘关联规则中Apriori算法的改进[J]. Computer Appl ications and Software,2004,21(11):82-83

[4]钱少华,蔡勇钱,雪忠.基于数组的Apriori算法的改进[J].计算机应用与软件.2006, 23(2):111-113.

[ 5]孟祥萍,钱进,刘大有.基于数组的关联规则挖掘算法[J].计算机工程.2003, 9

[6] 黄艳,王廷章,苑森森.一种高效相联规则提取算法[J]吉林大学自然

科学学报,2004,(2) :36-38

[7]季伟东,张珑,张军.一种Apriori算法的改进[J].计算机工程与科学.2009, 31(9):68-70.

[8]高宏宾,潘谷,黄义明.基于频繁项集特性的Apriori算法的改进[J].计算机工程与设计.2007, 28(10):2273-2275.

[9] 许晓东,李柯,朱士瑞.Web使用挖掘中Apriori算法的改进研究[J].计算机工程及设计.2010, 31(3):539-541.

相关主题
相关文档
最新文档