数据挖掘Apriori算法.docx
《数据挖掘Apriori算法.docx》由会员分享,可在线阅读,更多相关《数据挖掘Apriori算法.docx(14页珍藏版)》请在冰豆网上搜索。
![数据挖掘Apriori算法.docx](https://file1.bdocx.com/fileroot1/2023-2/8/97740339-eff3-46b5-b0b0-bd98cfb136f8/97740339-eff3-46b5-b0b0-bd98cfb136f81.gif)
数据挖掘Apriori算法
实验报告
实验课程名称:
数据挖掘
实验项目名称:
Apriori算法
理学院
实验时间:
2014年11月11日
学生所在学院:
理学院专业:
统计学班级:
姓名
学号
实验组
实验时间
指导教师
成绩
实验项目名称
Apriori算法
实验目的及要求:
1.加强对Apriori算法的理解
2.锻炼分析问题、解决问题以及动手能力
3.编程实现Apriori算法
实验(或算法)原理:
Apriori算法是一种找频繁项目集的基本算法。
其基本原理是逐层搜索的迭代:
频繁K项Lk集用于搜索频繁(K+1)项集Lk+1,如此下去,直到不能找到维度更高的频繁项集为止。
这种方法依赖连接和剪枝这两步来实现。
算法的第一次遍历仅仅计算每个项目的具体值的数量,以确定大型l项集。
随后的遍历,第k次遍历,包括两个阶段。
首先,使用在第(k-1)次遍历中找到的大项集Lk-1和用Aprioir-gen函数产生候选项集Ck。
接着扫描数据库,计算Ck中候选的支持度。
用Hash树可以有效地确定Ck中包含在一个给定的事务t中的候选。
算法如下:
(1) L1 = {大项目集1项目集};
(2) for (k = 2; Lk-1 !
= 空; k++) do begin
(3) Ck = apriori-gen(Lk-1);
."<map,unsignedint>empty;
returnempty;
}
while
(1)
{
map,unsignedint>K_itemTemp=K_item;
K_item=apri_gen(i++,K_item);
if(K_itemTemp==K_item)
{
i=UINT_MAX;
break;
}
//判断是否需要进行下一次的寻找
map,unsignedint>pre_K_item=K_item;
size_tKitemsize=();
//存储应该删除的第K级频繁项集,不能和其他K级频繁项集构成第K+1级项集的集合
if(Kitemsize!
=1&&i!
=1)
{
vector
:
iterator>eraseVecMit;
map,unsignedint>:
:
iteratorpre_K_item_it1=(),pre_K_item_it2;
while(pre_K_item_it1!
=())
{
map,unsignedint>:
:
iteratormit=pre_K_item_it1;
boolisExist=true;
vectorvec1;
vec1=pre_K_item_it1->first;
vectorvec11(),()-1);
while(mit!
=())
{
vectorvec2;
vec2=mit->first;
vectorvec22(),()-1);
if(vec11==vec22)
break;
++mit;
}
if(mit==())
isExist=false;
if(!
isExist&&pre_K_item_it1!
=())
(pre_K_item_it1);//该第K级频繁项应该删除
++pre_K_item_it1;
}
size_teraseSetSize=();
if(eraseSetSize==Kitemsize)
break;
else
{
vector
:
iterator>:
:
iteratorcurrentErs=();
while(currentErs!
=())//删除所有应该删除的第K级频繁项
{
map,unsignedint>:
:
iteratoreraseMit=*currentErs;
(eraseMit);
++currentErs;
}
}
}
else
if(Kitemsize==1)
break;
}
cout<showAprioriItem(i,K_item);
returnK_item;
}
map,unsignedint>Apriori:
:
apri_gen(unsignedintK,map,unsignedint>K_item)
{
if(1==K)//求候选集C1
{
size_tc1=item_size;
map>:
:
iteratormapit=();
vectorvec;
mapc1_itemtemp;
while(mapit!
=())//将原事务中所有的单项统计出来
{
vectortemp=mapit->second;
vector:
:
iteratorvecit=();
while(vecit!
=())
{
pair
:
iterator,bool>ret=(make_pair(*vecit++,1));
if(!
{
++>second;
}
}
++mapit;
}
map:
:
iteratoritem_it=();
map,unsignedint>c1_item;
while(item_it!
=())//构造第一级频繁项集
{
vectortemp;
if(item_it->second>=min_value)
{
(item_it->first);
(make_pair(temp,item_it->second));
}
++item_it;
}
returnc1_item;
}
else
{
cout<showAprioriItem(K-1,K_item);
map,unsignedint>:
:
iteratorck_item_it1=(),ck_item_it2;
map,unsignedint>ck_item;
while(ck_item_it1!
=())
{
ck_item_it2=ck_item_it1;
++ck_item_it2;
map,unsignedint>:
:
iteratormit=ck_item_it2;
//取当前第K级频繁项与其后面的第K级频繁项集联合,但要注意联合条件
//联合条件:
连个频繁项的前K-1项完全相同,只是第K项不同,然后两个联合生成第K+1级候选频繁项
while(mit!
=())
{
vectorvec,vec1,vec2;
vec1=ck_item_it1->first;
vec2=mit->first;
vector:
:
iteratorvit1,vit2;
vit1=();
vit2=();
while(vit1<()&&vit2<())
{
stringstr1=*vit1;
stringstr2=*vit2;
++vit1;
++vit2;
if(K==2||str1==str2)
{
if(vit1!
=()&&vit2!
=())
{
(str1);
}
}
else
break;
}
if(vit1==()&&vit2==())
{
--vit1;
--vit2;
stringstr1=*vit1;
stringstr2=*vit2;
if(str1>str2)
{
(str2);
(str1);
}
else
{
(str1);
(str2);
}
map>:
:
iteratorbase_item=();
unsignedintAcount=0;
while(base_item!
=())//统计该K+1级候选项在原事务集出现次数
{
unsignedintcount=0,mincount=UINT_MAX;
vectorvv=base_item->second;
vector:
:
iteratorvecit,bvit;
for(vecit=();vecit<();vecit++)
{
stringt=*vecit;
count=0;
for(bvit=();bvit<();bvit++)
{
if(t==*bvit)
count++;
}
mincount=(countmincount);
}
if(mincount>=1&&mincount!
=UINT_MAX)
Acount+=mincount;
++base_item;
}
if(Acount>=min_value&&Acount!
=0)
{
sort(),());
//该第K+1级候选项为频繁项,插入频繁项集
pair
:
iterator,bool>ret=(make_pair(vec,Acount));
if(!
{
>second+=Acount;
}
}
}
++mit;
}
++ck_item_it1;
}
if())//该第K+1级频繁项集为空,说明调用结束,把上一级频繁项集返回
returnK_item;
else
returnck_item;
}
}
voidApriori:
:
showAprioriItem(unsignedintK,map,unsignedint>showmap)
{
map,unsignedint>:
:
iteratorshowit=();
if(K!
=UINT_MAX)
cout<"<else
cout<<"最终的频繁项集为:
"<cout<<"项集"<<"\t"<<"频率"<while(showit!
=())
{
vectorvec=showit->first;
vector:
:
iteratorvecit=();
cout<<"{";
while(vecit!
=())
{
cout<<*vecit<<"";
++vecit;
}
cout<<"}"<<"\t";
cout<second<++showit;
}
}
unsignedintparseNumber(constchar*str)//对用户输入的数字进行判断和转换
{
if(str==NULL)
return0;
else
{
unsignedintnum=0;
size_tlen=strlen(str);
for(size_ti=0;i{
num*=10;
if(str[i]>='0'&&str[i]<='9')
num+=str[i]-'0';
else
return0;
}
returnnum;
}
}
voidmain()
{
//Aprioria;
unsignedintitemsize=0;
unsignedintmin;
do
{
cout<<"请输入事务数:
";
char*str=newchar;
cin>>str;
itemsize=parseNumber(str);
if(itemsize==0)
{
cout<<"请输入大于0正整数!
"<}
}while(itemsize==0);
do
{
cout<<"请输入最小支持度:
";
char*str=newchar;
cin>>str;
min=parseNumber(str);
if(min==0)
{
cout<<"请输入大于0正整数!
"<}
}while(min==0);
Aprioria(itemsize,min);
();
map,unsignedint>AprioriMap=();
//(UINT_MAX,AprioriMap);
system("pause");
}
运行的结果:
实验结果与讨论:
通过这次实验,我知道了Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集。
而且算法已经被广泛的应用到商业、网络安全等各个领域。
但是实验过程中发现Apriori算法的源代码好长,也好难。
不过经过和同学互相探讨,终于完成了本次实验。
指导教师意见:
签名:
年月日