数据挖掘与数据仓库.docx
《数据挖掘与数据仓库.docx》由会员分享,可在线阅读,更多相关《数据挖掘与数据仓库.docx(18页珍藏版)》请在冰豆网上搜索。
数据挖掘与数据仓库
华东交通大学
课程论文
数据仓库与数据挖掘
论文名称:
关联规则技术在数据挖掘中的应用
专业:
计算机应用技术
学生:
学号:
2013年6月20日
关联规则技术在数据挖掘中的应用
摘 要 数据挖掘技术的诞生,使我们能从大量的数据中提取对决策者有用的信息。
20世纪90年代初,R·Agrawal等人提出了关联规则挖掘技术,关联规则挖掘是为了发现大量数据中项目集之间感兴趣的相关性信息。
经过十余年的发展,关联规则挖掘已经成为数据挖掘技术中较为成熟并很重要的一种方法。
数据挖掘就是从大量的,不完全的,有噪声的,模糊的,随机的实际应用数据中,提取隐含在其中的,人们事先不知道的,但是又潜在有用的信息和知识的过程。
本文系统描述了关联规则挖掘所涉及的概念、关联规则挖掘算法和关联规则应用领域等,并且具体对实验做了分析。
关键字 数据挖掘;关联规则;Apriori挖掘算法
1 引言
关联分析就是对大量的数据进行分析,从中发现满足一定支持度和可信度的数据项之间的联系规则。
关联规则挖掘是数据挖掘研究的一个重要分支,关联规则是数据挖掘的众多知识类型中最为典型的一种。
该问题于1993年由Agrawal等人在对市场购物篮问题进行分析时首次提出用以发现商品销售中的顾客购买模式,以后诸多的研究人员对关联规则的挖掘问题进行了大量的研究。
他们的工作包括对原有的算法进行优化,如引入随机采样、并行的思想等,以提高算法挖掘规则的效率,对关联规则的应用进行推广。
数据挖掘有很广泛的应用领域。
其中,最广为人知且易于理解的就是关联规则了。
所谓关联规则,有时也称之为购物篮分析(marketbasketanalysis),其主要目的是在一个数据集中找出不同项之间的关系。
例如,购买鞋的顾客,有10%的可能也会买袜子;60%的买面包的顾客,也会买牛奶。
一个有名的例子就是"尿布和啤酒"的故事了。
美国沃尔玛连锁店超市里,有一个有趣的现象:
尿布和啤酒赫然摆在一起出售,表面上看似毫不相关的商品。
但是这个奇怪的举措却使尿布和啤酒的销量都增加了。
有人分析,原因可能是美国的妇女们经常会嘱咐她们的丈夫下班以后要为孩子买尿布。
而丈夫在买完尿布之后又要顺手买回自己爱喝的啤酒,因此啤酒和尿布在一起购买的机会就变得很大了。
沃尔玛是如何发现了尿布和啤酒之间的关系呢?
正是数据挖掘的关联规则思想。
商家请人对超市一年多原始交易数字进行了详细的分析,分析的结果揭示了这对神奇的组合。
关联规则在其它应用场合也有很好的应用。
例如:
在商业销售上,关联规则可用于交叉销售,以得到更大的收入;在保险业务方面,如果出现了不常见的索赔要求组合,则可能为欺诈,需要作进一步的调查。
在医疗方面,可找出可能的治疗组合;在银行方面,对顾客进行分析,可以推荐感兴趣的服务等等。
2 关联规则算法
2.1关联规则挖掘的过程
近年来,关联规则挖掘研究成为数据挖掘中的一个热点,并被广泛应用于市场营销、事务分析等应用领域。
关联规则挖掘算法是关联规则挖掘研究的主要内容,迄今为止已提出了许多高效的关联规则挖掘算法。
发现关联规则的任务就是要找出满足预先指定的频率和精度标准的所有规则。
这个任务看起来似乎是令人望而生畏的,因为潜在的频繁集数量是与变量数和数据数呈指数关系的。
幸运的是,在实际数据集中的情况下,通常频繁集数量是比较小的。
关联规则挖掘过程主要包含两个阶段:
第一阶段必须先从资料集合中找出所有的高频项目组(FrequentItemsets),第二阶段再由这些高频项目组中产生关联规则(AssociationRules)。
关联规则挖掘的第一阶段必须从原始资料集合中,找出所有高频项目组(LargeItemsets)。
高频的意思是指某一项目组出现的频率相对于所有记录而言,必须达到某一水平。
一项目组出现的频率称为支持度(Support),以一个包含A与B两个项目的2-itemset为例,我们可以经由公式
(1)求得包含{A,B}项目组的支持度,若支持度大于等于所设定的最小支持度(MinimumSupport)门槛值时,则{A,B}称为高频项目组。
一个满足最小支持度的k-itemset,则称为高频k-项目组(Frequentk-itemset),一般表示为Largek或Frequentk。
算法并从Largek的项目组中再产生Largek+1,直到无法再找到更长的高频项目组为止。
关联规则挖掘的第二阶段是要产生关联规则(AssociationRules)。
从高频项目组产生关联规则,是利用前一步骤的高频k-项目组来产生规则,在最小信赖度(MinimumConfidence)的条件门槛下,若一规则所求得的信赖度满足最小信赖度,称此规则为关联规则。
例如:
经由高频k-项目组{A,B}所产生的规则AB,其信赖度可经由公式
(2)求得,若信赖度大于等于最小信赖度,则称AB为关联规则。
就沃尔马案例而言,使用关联规则挖掘技术,对交易资料库中的纪录进行资料挖掘,首先必须要设定最小支持度与最小信赖度两个门槛值,在此假设最小支持度min_support=5%且最小信赖度min_confidence=70%。
因此符合此该超市需求的关联规则将必须同时满足以上两个条件。
若经过挖掘过程所找到的关联规则「尿布,啤酒」,满足下列条件,将可接受「尿布,啤酒」的关联规则。
用公式可以描述Support(尿布,啤酒)>=5%且Confidence(尿布,啤酒)>=70%。
其中,Support(尿布,啤酒)>=5%于此应用范例中的意义为:
在所有的交易纪录资料中,至少有5%的交易呈现尿布与啤酒这两项商品被同时购买的交易行为。
Confidence(尿布,啤酒)>=70%于此应用范例中的意义为:
在所有包含尿布的交易纪录资料中,至少有70%的交易会同时购买啤酒。
因此,今后若有某消费者出现购买尿布的行为,超市将可推荐该消费者同时购买啤酒。
这个商品推荐的行为则是根据「尿布,啤酒」关联规则,因为就该超市过去的交易纪录而言,支持了“大部份购买尿布的交易,会同时购买啤酒”的消费行为。
从上面的介绍还可以看出,关联规则挖掘通常比较适用与记录中的指标取离散值的情况。
如果原始数据库中的指标值是取连续的数据,则在关联规则挖掘之前应该进行适当的数据离散化(实际上就是将某个区间的值对应于某个值),数据的离散化是数据挖掘前的重要环节,离散化的过程是否合理将直接影响关联规则的挖掘结果。
2.2关联规则的分类
按照不同情况,关联规则可以进行分类如下:
1.基于规则中处理的变量的类别,关联规则可以分为布尔型和数值型。
布尔型关联规则处理的值都是离散的、种类化的,它显示了这些变量之间的关系;而数值型关联规则可以和多维关联或多层关联规则结合起来,对数值型字段进行处理,将其进行动态的分割,或者直接对原始的数据进行处理,当然数值型关联规则中也可以包含种类变量。
例如:
性别=“女”=>职业=“秘书”,是布尔型关联规则;性别=“女”=>avg(收入)=2300,涉及的收入是数值类型,所以是一个数值型关联规则。
2.基于规则中数据的抽象层次,可以分为单层关联规则和多层关联规则。
在单层的关联规则中,所有的变量都没有考虑到现实的数据是具有多个不同的层次的;而在多层的关联规则中,对数据的多层性已经进行了充分的考虑。
例如:
IBM台式机=>Sony打印机,是一个细节数据上的单层关联规则;台式机=>Sony打印机,是一个较高层次和细节层次之间的多层关联规则。
3.基于规则中涉及到的数据的维数,关联规则可以分为单维的和多维的。
在单维的关联规则中,我们只涉及到数据的一个维,如用户购买的物品;而在多维的关联规则中,要处理的数据将会涉及多个维。
换成另一句话,单维关联规则是处理单个属性中的一些关系;多维关联规则是处理各个属性之间的某些关系。
例如:
啤酒=>尿布,这条规则只涉及到用户的购买的物品;性别=“女”=>职业=“秘书”,这条规则就涉及到两个字段的信息,是两个维上的一条关联规则。
2.3Apriori算法:
使用候选项集找频繁项集
Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。
其核心是基于两阶段频集思想的递推算法。
该关联规则在分类上属于单维、单层、布尔关联规则。
在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集。
该算法的基本思想是:
首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。
然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。
然后使用第1步找到的频集产生期望的规则,产生只包含集合的项的所有规则,其中每一条规则的右部只有一项,这里采用的是中规则的定义。
一旦这些规则被生成,那么只有那些大于用户给定的最小可信度的规则才被留下来。
为了生成所有频集,使用了递推的方法。
可能产生大量的候选集,以及可能需要重复扫描数据库,是Apriori算法的两大缺点。
简单地说,关联规则的目标是发现出现频度较高的组合。
比如假设上图中,DatabaseTDB中A、B、C、D、E分别代表不同的商品,Tid=10的用户同时购买了A,C,D三种商品,Tid=20的用户同时购买了B,C,E三种商品,等等。
该算法寻找所有出现次数超过支持度的子项。
所谓支持度,就是至少要出现的次数。
例如,A,C的组合共出现了2次(Tid=10和30),它的支持度就是2。
对用户给定一个支持度,Apirori算法每次扫描,把出现次数不够支持度的项从候选集中去除,然后再在此基础上生成更多项组合的子集。
做一个简单的关联规则的数据挖掘。
为了简化,只做两项组合的频繁集,题目中的商品也只用一个字母代替。
输入:
最小支持度support(>1),交易记录的数量N,紧跟着是N个具体的交易记录。
输出:
所有支持度≥support的二项组合,以及对应的支持度。
样例输入:
2□4↵
a,c,d↵
b,c,e↵
a,b,c,e↵
b,e↵
样例输出:
a,c:
2↵
b,c:
2↵
b,e:
3↵
c,e:
2↵
importjava.util.Scanner;
publicclassMain{
publicstaticvoidmain(String[]args){
StringBuildersBuilder=newStringBuilder();
Scannerscanner=newScanner(System.in);
Stringstr=scanner.nextLine();
String[]in=str.split("");
intsupport=Integer.parseInt(in[0]);
intN=Integer.parseInt(in[1]);
String[]arr=newString[N];
for(inti=0;iarr[i]=scanner.nextLine().replaceAll(",","");//把读入的字符串去除",",由a,b,c,d变成abcd
}
scanner.close();
for(inti=0;iintlen1=arr[i].length();
for(intj=0;jfor(intk=j+1;kStrings=arr[i].charAt(j)+","+arr[i].charAt(k);
sBuilder.append(s).append("");
}
}
}
StringtString=sBuilder.toString().trim();//两个两个连接完成的数组,去除最后的空格
String[]result=tString.split("");//把连接成的字符串再分成数组,便于查找
intlen2=result.length;
sBuilder=newStringBuilder();//把sBuilder置为空值
for(inti=0;iintnum=1;
for(intj=i+1;jif(result[i].equals(result[j])){
num++;
}
}
if(num>=support&&sBuilder.indexOf(result[i])==-1){//判断是否已经输出过
sBuilder.append(result[i]).append("");//没有输出过就添加到sBuilder判断
System.out.println(result[i]+":
"+num);
}
}
}
}
3.基于Apriori的算法优化和改进
为了提高Apriori算法的效率,人们对该算法进行了优化和变形,其中算法的变化主要集中在两点:
产生候选项集的方法和候选项集支持度的计算。
以下是一些典型的优化算法:
(1)基于HASH的算法:
在Apriori算法产生候选项频繁集的过程中,如何高效产生频繁2-项集是提高数据挖掘性能的关键,DHP(Directhashingandpruning)算法很好地解决了这一问题。
使用该算法产生频繁项集的过程分几步:
首先获得频繁1-项集并且产生候选2-项集的散列表;然后基于散列表产生候选2-项集,进而得到频繁2-项集并且产生3-项集的散列表…直到产生频繁K-项集。
这种基于散列技术大大减少了需要考虑的K-项集的个数,尤其是2-项集,并且随着K的增加候选项集的个数急剧减小,解决了性能上的瓶颈问题。
(2)基于划分的算法:
当数据库中的数据量特别大时,对数据进行处理是很困难的,基于划分的算法可以在不增加I/O和CPU使用的基础上解决这一问题。
该算法分两步进行:
第一步根据内存容量,在逻辑上把交易数据库划分为若干非重叠的部分,然后把每个部分看作一个独立的数据库寻找其中的频繁集,即局部频繁集。
在第一步结束时把每个划分的局部频繁集进行合并得到全局频繁集的候选集。
第二步计算每个局部频繁集在原交易数据库中的支持度,得到全局频繁集。
使用基于划分的算法只需要对数据库进行两次扫描,分别用于产生全局频繁集的候选项集和计算该候选项集的支持度。
使用这种方法将数据库进行划分后,由于每个部分之间没有共享数据,可以使用并行算法进行处理提高效率。
引入并行算法后,整个算法可以分为四步:
将数据库划分后每个部分称为结点,第一步每个节点独立计算各自的局部频繁集;第二步将结点间不同的频繁集相互交换,最终使所有结点的频繁集相同;第三步在每个节点重新计算合并后的局部频繁项集的支持度(localcounts),最后将每个局部频繁项集在每个结点的支持度相加得到每个项集的全局支持度。
(3)基于采样的算法:
针对大型数据库可以使用基于采样的算法挖掘其中的关联规则。
首先由数据库中随机采样得到的数据产生可能在整个数据库范围满足参数指标的规则,然后使用剩余数据对这些规则进行检验。
为了不遗漏可能满足设定参数的频繁集,对于采样数据集一般使用比用户定义的最小支持度小的支持度阐值。
基于采样的算法是一种在精确度和效率之间取得平衡的方法,这种算法减少了扫描次数,显著降低了I/0代价,但是牺牲了一些精度,即存在数据扭曲问题。
(4)减少事务数:
根据Apriori性质,当一个事务中不包含K-项集时,它一定不包含K+1-项集,这样可以给这些事务加上标记,在下一次扫描数据库时对这些事务不予考虑,减少需要扫描的事务数。
对于很多的应用来说,由于数据分布的分散性,所以很难在数据最细节的层次上发现一些强关联规则。
当我们引入概念层次后,就可以在较高的层次上进行挖掘。
虽然较高层次上得出的规则可能是更普通的信息,但是对于一个用户来说是普通的信息,对于另一个用户却未必如此。
所以数据挖掘应该提供这样一种在多个层次上进行挖掘的功能。
多层关联规则的分类:
根据规则中涉及到的层次,多层关联规则可以分为同层关联规则和层间关联规则。
多层关联规则的挖掘基本上可以沿用“支持度-可信度”的框架。
不过,在支持度设置的问题上有一些要考虑的东西。
对于多维数据库而言,除维内的关联规则外,还有一类多维的关联规则。
例如:
年龄(X,“20。
。
。
30”)职业(X,“学生”)==>购买(X,“笔记本电脑”)在这里我们就涉及到三个维上的数据:
年龄、职业、购买。
根据是否允许同一个维重复出现,可以又细分为维间的关联规则(不允许维重复出现)和混合维关联规则(允许维在规则的左右同时出现)。
年龄(X,“20。
。
。
30”)购买(X,“笔记本电脑”)==>购买(X,“打印机”)
这个规则就是混合维关联规则。
在挖掘维间关联规则和混合维关联规则的时候,还要考虑不同的字段种类:
种类型和数值型。
对于种类型的字段,原先的算法都可以处理。
而对于数值型的字段,需要进行一定的处理之后才可以进行。
4实验实验
4.1算法原理
Aprior使用一种称作逐层搜索的迭代方法,K项集用于搜索(K+1)项集。
首先,通过扫描数据库,累积每个项的计数,并收集满足最小支持度的项,找出频繁1项集的集合。
该集合记作L1。
然后,L1用于寻找频繁2项集的集合L2,L2用于寻找L3,如此下去,直到不能再找到频繁K项集。
为提高频繁项集逐层产生的效率,一种称作Apriori的重要性质用于压缩搜索空间。
Apriori性质:
频繁项集的所有非空子集也必须是频繁的。
如何在算法中使用Apriori性质?
主要有两步过程组成:
连接步和剪枝步。
(1)连接步:
为找L(k),通过将L(k-1)与自身连接产生候选K项集的集合。
该候选项集合记作C(K)。
设l1和l2是L(k-1)中的项集。
记号l(i)[j]表示l(i)中的第j项。
执行L(k-1)连接L(k-1),如果它们的前(K-2)项相同的话,其中L(k-1)的元素是可连接的。
(2)剪枝步:
为压缩C(K),可以用Apriori的性质:
任何非频繁的(K-1)项集都不是频繁K项集的子集。
因此,如果候选K项集的(K-1)项子集不在L(k-1)中,则该候选也不可能是频繁的,从而可以从C(K)中删除。
4.2算法步骤
算法第一步是简单统计所有含一个元素的项集出现的频率,来决定最大的一维项目
集,在第k步,分两个阶段,首先用一函数sc_candidate,通过第(k-1)步中生成最大项
目集来生成候选项目集,然后搜素数据库计算候选项目集的支持度。
Apriori算法描述如下:
(1)={candidate1-itemset};
(2)={c|c.countminsupport};
(3)For(k=2,,k++)
(4)=sc_candidate();
(5)foralltransactiontD
(6)=count_support(,t)
(7)forallcandidatesc
(8)c.count=c.count+1;
(9)next
(10)={c|c.countminsupport};
(11)Next
(12)Resultset=resultset
其中,D表示数据库;minsupport表示给定的最小支持度;resultset表示所有最大项目
集。
k-itemset表示k维项目集;:
具有最小支持度的最大k-itemset;:
候选的k-
itemset(潜在最大项目集)
4.3程序流程图
程序的主体部分首先接收用户输入的最小支持度,之后读取原始数据。
产生频繁1项集的集合
,之后用
产生候选
,以找出
,其中k>=2;
如图1所示是Apriori算法的程序流程图。
图1Apriori算法流程图
4.4实验结果分析
1.当输入的最小支持度为2的时候,此时程序的运行时间是比较长的。
运行结果如图2所示:
图2最小支持度=2时的结果图
2.当当输入的最小支持度较大的时候,此算法产生频繁项集的效率挺快的。
例如,最小支持度7的时候,程序运行结果如图3所示:
图3最小支持度=7时的结果图
4.5与Weka关联规则之Apriori之比较
publicvoidGetAssociationRules1()
{
try{
Discretizediscretize=newDiscretize();
discretize.setInputFormat(m_instances);
m_instances=Filter.useFilter(m_instances,discretize);
Aprioriapriori=newApriori();
apriori.buildAssociations(m_instances);
System.out.println(apriori.toString());
}catch(Exceptione)
{
e.printStackTrace();
}
}publicstaticvoidmain(String[]args)throwsException
{
AssociationTestat=newAssociationTest();
at.LoadInstances("F:
\\ProgramFiles\\Weka-3-6\\data\\iris.arff");
at.GetAssociationRules();
}
我只需要得到它的规则,所以只分析了一点它的toString代码:
Utils.doubleToString((double)i+1,(int)(Math.log(m_numRules)
/Math.log(10)+1),0)
(double)i+1表示第几个规则,而(int)(Math.log(m_numRules)/Math.log(10)+1)表示要用几位来表示,因为十进制所以除以log(10)。
比如有20个规则就是2,如果是200个规则就是3位,最后一个参数表示小数点后保留几位。
((AprioriItemSet)m_allTheRules[0].elementAt(i)).toString(m_instances)
这里是取m_allTheRules[0]的第i个元素,allTheRules[0]是关联规则的左部,第i个元素则是第几个规则,再看AprioriItemSet.toString(Instances)函数,它调用父类ItemSet的toString函数。
publicfinalStringtoString(Instancesinstances){
returnsuper.toString(instances);
}
termsSet的toString如下:
publicStringtoString(Instancesinstances){
StringBuffertext=newStringBuffer();
for(inti=0;iif(m_items[i]!
=-1){
text.a