数据挖掘Apriori算法报告周一Word格式文档下载.docx
《数据挖掘Apriori算法报告周一Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据挖掘Apriori算法报告周一Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
一个是可能产生大量的候选集,另一个是需要重复扫描数据库.因此如果挖掘数据仓库数据量很大,应用此算法每次迭代产生候选项集用来统计其支持度需要花费很多时间。
为了提高算法的效率,国内外专家学者提出的一系列改进算法主要从减少扫描数据库的次数和减少生成候选项目集的数目方面进行优化。
从近几年频繁项集挖掘算法的研究趋势来看,为了提高算法的效率,提出了一系列的混合搜索策略和高效剪枝策略。
当数据集中所包含的项目个数比较多时,马占欣,陆玉昌提出只有恰当地设置2个额外参数,才能够保证挖掘过程的正常进行,但这样做的代价是可能会遗漏部分包含更多负项目的关联规则。
二.关联算法的基本原理
该算法的基本思想是:
首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。
然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。
然后使用第1步找到的频集产生期望的规则,产生只包含集合的项的所有规则,其中每一条规则的右部只有一项,这里采用的是中规则的定义。
一旦这些规则被生成,那么只有那些大于用户给定的最小可信度的规则才被留下来。
为了生成所有频集,使用了递推的方法
<
1)L1=find_frequent_1-itemsets(D>
//挖掘频繁1-项集,比较容易
2)for(k=2。
Lk-1≠Φ。
k++>
{
3)Ck=apriori_gen(Lk-1,min_sup>
//调用apriori_gen方法生成候选频繁k-项集
4)foreachtransactiont∈D{
//扫描事务数据库D
5)Ct=subset(Ck,t>
6)foreachcandidatec∈Ct
7)c.count++。
//
统计候选频繁k-项集的计数
8)}
9)Lk={c∈Ck|c.count≥min_sup}//满足最小支持度的k-项集即为频繁k-项集
10)}
11)returnL=∪kLk。
//合并频繁k-项集<
k>
0)
三.关联算法的C++简单实现
3.1算法数据:
对给定数据集用Apriori算法进行挖掘,找出其中的频繁集并生成关联规则。
对下面数据集进行挖掘:
I1I2I5
I1I2
I2I4
I1I2I4
I1I3
I1I2I3I5
I1I2I3
I2I5
I2I3I4
I3I4
对于数据集,取最小支持度minsup=2,最小置信度minconf=0.8。
3.2算法步骤:
①首先单趟扫描数据集,计算各个一项集的支持度,根据给定的最小支持度闵值,得到一项频繁集L1。
②然后通过连接运算,得到二项候选集,对每个候选集再次扫描数据集,得出每个候选集的支持度,再与最小支持度比较。
得到二项频繁集L2。
③如此进行下去,直到不能连接产生新的候选集为止。
④对于找到的所有频繁集,用规则提取算法进行关联规则的提取。
3.3C++算法的简单实现
①首先要在项目名文件夹里自己定义date.txt文档存放数据,然后在main函数中用FILE*fp=fopen("
date.txt"
"
r"
>
将数据导入算法。
②定义intcountL1[10]。
找到各一维频繁子集出现的次数。
定义charcurL1[20][2]。
实现出现的一维子集。
因为给出的数据最多有4个数,所以同样的我们要定义到4维来放数据。
intcountL2[10]。
//各二维频繁子集出现的次数
charcurL2[20][3]。
//出现的二维子集
intcountL3[10]。
//各三维频繁子集出现的次数
charcurL3[20][4]。
//出现的三维子集
charcur[50][4]。
③定义intSizeStr(char*m>
得到字符串的长度。
实现代码如下:
intSizeStr(char*m>
{
inti=0。
while(*(m+i>
!
=0>
i++。
}
returni。
}
④比较两个字符串,如果相等返回true,否则返回false
boolOpD(char*x,char*y>
if(SizeStr(x>
==SizeStr(y>
while(*(x+i>
==*(y+i>
{
i++。
if(*(x+i>
==0&
&
*(y+i>
==0>
returntrue。
}
returnfalse。
⑤通过voidLoadItemL1(char**p>
得到所有1元的字串和各自出现的次数
voidLoadItemL1(char**p>
inti,j,n=0,k=0。
charch。
char*s。
intf。
memset(cur,0,sizeof(cur>
for(i=0。
i<
20。
i++>
curL1[i][0]=0。
curL1[i][1]=0。
for(j=0。
j<
10。
j++>
countL1[j]=0。
for(j=0。
4。
ch=*(*(p+i>
+j>
if(ch==0>
break。
cur[n][0]=ch。
n++。
curL1[0][0]=cur[0][0]。
curL1[0][1]=cur[0][1]。
k=0。
50。
if(cur[i]==0>
break。
s=cur[i]。
f=1。
=k。
if(OpD(s,curL1[j]>
{
f=0。
}
if(f==1>
++k。
curL1[k][0]=cur[i][0]。
curL1[k][1]=cur[i][1]。
char*m。
m=curL1[i]。
if(*m==0>
if(OpD(m,cur[j]>
countL1[i]++。
printf("
L1:
\n"
项集支持度计数\n"
if(curL1[i]==0>
if(countL1[i]>
=2>
printf("
{I%s}:
%d\n"
curL1[i],countL1[i]>
⑥通过voidSubItem2(char**p>
得到所有的2元子串
voidSubItem2(char**p>
inti,j,k,n=0。
curL2[i][0]=0。
curL2[i][1]=0。
curL2[i][2]=0。
countL2[i]=0。
for(k=0。
k<
s=*(p+k>
if(SizeStr(s>
2>
continue。
for(i=0。
SizeStr(s>
for(j=i+1。
if(*(s+j>
break。
*(cur[n]+0>
=*(s+i>
*(cur[n]+1>
=*(s+j>
*(cur[n]+2>
=0。
*(cur[n]+3>
n++。
⑦通过voidLoadItemL2(char**p>
得到各个2元频繁子串出现的次数
voidLoadItemL2(char**p>
intk,i,j。
SubItem2(p>
curL2[0][0]=cur[0][0]。
curL2[0][1]=cur[0][1]。
curL2[0][2]=cur[0][2]。
if(OpD(s,curL2[j]>
curL2[k][0]=cur[i][0]。
curL2[k][1]=cur[i][1]。
curL2[k][2]=cur[i][2]。
s=curL2[i]。
if(*s==0>
if(OpD(s,cur[j]>
countL2[i]++。
L2:
\n"
if(curL2[i]==0>
if(countL2[i]>
{I%c,I%c}:
curL2[i][0],curL2[i][1],countL2[i]>
⑧通过定义voidSubItem3(char**p>
得到所有3元的子串
voidSubItem3(char**p>
char*s。
inti,j,h,m。
intn=0。
curL3[j][0]=0。
curL3[j][1]=0。
curL3[j][2]=0。
curL3[j][3]=0。
countL3[i]=0。
for(m=0。
m<
m++>
s=*(p+m>
3>
for(h=j+1。
h<
h++>
{
if(*(s+h>
break。
*(cur[n]+0>
*(cur[n]+1>
*(cur[n]+2>
=*(s+h>
*(cur[n]+3>
n++。
}
⑨同样我们要得到得到各个3元频繁子串出现的次数
voidLoadItemL3(char**p>
SubItem3(p>
curL3[0][0]=cur[0][0]。
curL3[0][1]=cur[0][1]。
curL3[0][2]=cur[0][2]。
curL3[0][3]=cur[0][3]。
if(OpD(s,curL3[j]>
curL3[k][0]=cur[i][0]。
curL3[k][1]=cur[i][1]。
curL3[k][2]=cur[i][2]。
curL3[k][3]=cur[i][3]。
s=curL3[i]。
countL3[i]++。
L3:
if(curL3[i]==0>
if(countL3[i]>
{I%c,I%c,I%c}:
curL3[i][0],curL3[i][1],curL3[i][2],countL3[i]>
⑩定义voidLoadItemL4(char**p>
得到各个3元子串出现的次数
voidLoadItemL4(char**p>
inti。
intj=0。
s=*(p+i>
==4>
j++。
四维子集出现的次数:
j>
没有四维的频繁子集,算法结束!
通过voidSupport(char*w,intg>
得到关联规则,并输出结果
voidSupport(char*w,intg>
floatc=0.8,d=0。
s=w。
*(cur[n]+0>
*(cur[n]+1>
*(cur[n]+2>
*(cur[n]+3>
n++。
for(j=i+1。
if(*(s+j>
*(cur[n]+0>
*(cur[n]+1>
*(cur[n]+2>
*(cur[n]+3>
if(SizeStr(cur[i]>
==1>
for(j=0。
if(OpD(cur[i],curL1[j]>
d=countL3[g]/(float>
countL1[j]。
if(d>
=c>
printf("
%f"
curL1[i],d>
==2>
if(OpD(cur[i],curL2[j]>
countL2[j]。
%f\n"
curL2[j][0],curL2[j][1],d>
最后通过main函数完成整过程序
intmain(intargc,char*argv[]>
inti=0,j=0,k。
charbuf[10][6]。
char*p[10]。
memset(buf,0,sizeof(buf>
FILE*fp=fopen("
if(fp==NULL>
return0。
ch=fgetc(fp>
while(ch!
=EOF>
if(ch==0xa||ch==0xd>
ch=fgetc(fp>
j=0。
buf[i][j]=ch。
j++。
ch=fgetc(fp>
*(p+k>
=buf[k]。
LoadItemL1(p>
LoadItemL2(p>
LoadItemL3(p>
LoadItemL4(p>
产生关联规则:
非空子集:
置信度:
\n"
if(curL3[i]!
=0&
countL3[i]>
Support(curL3[i],i>
return0。
3.4程序输出结果:
四.学习心得体会
关联算法基本原理学习思路简单,只需一步一步找出频集。
再通过支持度算出可信度,如对于A—>
C,support=support<
{A,C}),confidence=support<
{A,C})/support<
{A})。
其中频繁子集的任何子集一定是频繁的,子集频繁父亲一定频繁。
相对较难的的部分在于C++代码的实现部分依次实现各个频繁子集,完成整个程序。
这学期在商务智能课中学习了数据挖掘的10大算法,数据挖掘十分经典,掌握好一个简单的算法要下很功夫,在今后的工作中一定可以用到,我很庆幸这学期能选到这个课,在这之前听说过数据挖掘但一直没有机会接触,原理容易理解但没接触到以前就没有想过这样考虑问题,学习这个课程以后无论是知识面,智力上都是一个跳跃。
还有也提醒我要多复习C++问题的思考,这学期一直忙于网页编程,忘记了上学期说要复习C++数据结构的学习。
希望以后还有机会能选到老师的课。
申明:
所有资料为本人收集整理,仅限个人学习使用,勿做商业用途。