频繁模式挖掘算法(Apriori)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
由于给出的数据最多有4个数,所以同样的我们要定义到4维来放数据。
int countL2[10]; //各二维频繁子集出现的次数
char curL2[20][3]; //出现的二维子集
int countL3[10]; //各三维频繁子集出现的次数
char curL3[20][4]; //出现的三维子集
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];
k=0;
for(i=0;i<50;i++)
{
if(cur[i]==0)
break;
s=cur[i];
for(i=0;i<20;i++)
{
curL2[i][0]=0;
curL2[i][1]=0;
curL2[i][2]=0;
}
for(i=0;i<10;i++)
countL2[i]=0;
for(k=0;k<10;k++)
{
s=*(p+k);
if(SizeStr(s)<2)
continue;
for(i=0;i<SizeStr(s);i++)
for(j=i+1;j<SizeStr(s);j++)
{
if(*(s+j)==0)
break;
*(cur[n]+0)=*(s+i);
*(cur[n]+1)=*(s+j);
*(cur[n]+2)=0;
*(cur[n]+3)=0;
n++;
}
}
}
7)通过void LoadItemL2(char **p)得到各个2元频繁子串出现的次数
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL3[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL3[k][0]=cur[i][0];
curL3[k][1]=cur[i][1];
curL3[k][2]=cur[i][2];
curL3[k][3]=cur[i][3];
void LoadItemL2(char **p)
{
int k,i,j;
char* s;
int f;
SubItem2(p);
curL2[0][0]=cur[0][0];
curL2[0][1]=cur[0][1];
curL2[0][2]=cur[0][2];
k=0;
for(i=0;i<50;i++)
{
for(m=0;m<10;m++)
{
s=*(p+m);
if(SizeStr(s)<3)
continue;
for(i=0;i<SizeStr(s);i++)
for(j=i+1;j<SizeStr(s);j++)
{
for(h=j+1;h<SizeStr(s);h++)
{
if(*(s+h)==0)
break;
Return true;
Return false;
四、实验要求
1、数据集具有一定的代表性,可以使用数据库技术管理
2、最小支持度和置信度可以设置
3、实现界面友好
4、提交实验报告:实验题目、目的、数据集描述、实验环境、过程、结果和分析等。
五、实验步骤
1、所采用的数据集
I1 I2 I5
I1 I2
I2 I4
{
if(cur[i]==0)
break;
s=cur[i];
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL1[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL1[k][0]=cur[i][0];
curL1[k][1]=cur[i][1];
}
}
for(i=0;i<20;i++)
If((l1[1]=l2[1])&&( l1[2]=l2[2])&&........
&& (l1[k-2]=l2[k-2])&&(l1[k-1]<l2[k-1])) then{
c=l1连接l2 //连接步:产生候选
if has_infrequent_subset(c,Lk-1) then
delete c; //剪枝步:删除非频繁候选
void LoadItemL1(char **p)
{
int i,j,n=0,k=0;
char ch;
char* s;
int f;
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++)
3、程序实现
1)首先要在工程名文件夹里自己定义date.txt文档存放数据,然后在main函数中用FILE* fp=fopen("date.txt","r");将数据导入算法。
2)定义int countL1[10];找到各一维频繁子集出现的次数。
定义char curL1[20][2];实现出现的一维子集。
for(j=0;j<50;j++)
{
char* m;
m=curL1[i];
if(*m==0)
break;
if(OpD(m,cur[j]))
countL1[i]++;
}
printf("L1: \n ");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL1[i]==0)
*(cur[n]+0)=*(s+i);
*(cur[n]+1)=*(s+j);
*(cur[n]+2)=*(s+h);
*(cur[n]+3)=0;
n++;
}
}
}
}
9)同样我们要得到得到各个3元频繁子串出现的次数
void LoadItemL3(char** p)
{
int k,i,j;
char* s;
int f;
countL1[j]=0;
for(i=0;i<10;i++)
for(j=0;j<4;j++)
{
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;
for(i=0;i<50;i++)
break;
if(countL1[i]>=2)
printf("{I%s}: %d\n",curL1[i],countL1[i]);
}
}
6)通过void SubItem2(char **p)得到所有的2元子串
void SubItem2(char **p)
{
int i,j,k,n=0;
char* s;
memset(cur,0,sizeof(cur));
break;
if(countL3[i]>=2)
printf("{I%c,I%c,I%c}: %d\n",curL3[i][0],curL3[i][1],curL3[i][2],countL3[i]);
实验一频繁模式挖掘算法(Apriori)
一、实验目的
1、理解频繁模式和关联规则
2、掌握频繁模式挖掘算法Apriori
3、为改进Apriori打下基础
二、实验内容
1、选定一个数据集(可以参考教学中使用的数据集)
2、选择合适的实现环境和工具实现算法,本次试验采用的是C++
3、根据设置的最小支持度和置信度,给出数据集的频繁模式集
Apriori性质:频繁项集的所有非空子集也必是频繁的。Apriori算法主要包括连接步和剪枝步两步组成。在连接步和剪枝步中采用Apriori性质可以提高算法的效率。
Apriori伪代码
算法:Apriori
输入:D -事务数据库;min_sup -最小支持度计数阈值
输出:L - D中的频繁项集
方法:
int i,j,h,m;
int n=0;
memset(cur,0,sizeof(cur));
for(j=0;j<20;j++)
{
curL3[j][0]=0;
curL3[j][1]=0;
curL3[j][2]=0;
curL3Байду номын сангаасj][3]=0;
}
for(i=0;i<10;i++)
countL3[i]=0;
For each候选c属于Ct
c.count++;
}
Lk={c属于Ck | c.count>=min_sup}
}
Return L=所有的频繁集;
Procedure apriori_gen(Lk-1:frequent(k-1)-itemsets)
For each项集l1属于Lk-1
For each项集l2属于Lk-1
if(cur[i]==0)
break;
s=cur[i];
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL2[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL2[k][0]=cur[i][0];
curL2[k][1]=cur[i][1];
curL2[k][2]=cur[i][2];
L1=find_frequent_1-itemsets(D); //找出所有频繁1项集
For(k=2;Lk-1!=null;k++){
Ck=apriori_gen(Lk-1); //产生候选,并剪枝
For each事务t in D{ //扫描D进行候选计数
Ct =subset(Ck,t); //得到t的子集
char cur[50][4];
3)定义int SizeStr(char* m)得到字符串的长度。实现代码如下:
int SizeStr(char* m)
{
int i=0;
while(*(m+i)!=0)
{
i++;
}
return i;
}
4)比较两个字符串,如果相等返回true,否则返回false
bool OpD(char* x,char* y)
else add c to Ck;
}
Return Ck;
Procedure has_infrequent_sub(c:candidate k-itemset; Lk-1:frequent(k-1)-itemsets)
For each(k-1)-subset s of c
If s不属于Lk-1 then
break;
if(countL2[i]>=2)
printf("{I%c,I%c}: %d\n",curL2[i][0],curL2[i][1],countL2[i]);
}
}
8)通过定义void SubItem3(char **p)得到所有3元的子串
void SubItem3(char **p)
{
char *s;
{
int i=0;
if(SizeStr(x)==SizeStr(y))
{
while(*(x+i)==*(y+i))
{
i++;
if(*(x+i)==0 && *(y+i)==0)
return true;
}
}
return false;
}
5)通过void LoadItemL1(char **p)得到所有1元的字串和各自出现的次数
}
}
for(i=0;i<20;i++)
for(j=0;j<50;j++)
{
s=curL2[i];
if(*s==0)
break;
if(OpD(s,cur[j]))
countL2[i]++;
}
printf("L2: \n");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL2[i]==0)
}
}
for(i=0;i<20;i++)
for(j=0;j<50;j++)
{
s=curL3[i];
if(*s==0)
break;
if(OpD(s,cur[j]))
countL3[i]++;
}
printf("L3: \n");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL3[i]==0)
三、实验原理
该算法的基本思想是:Apriori使用一种称作逐层搜索的迭代方法,k项集用于探索(k+1)项集。首先,通过扫描数据库,累积每个项的计数,并收集满足最小支持度的项,找出频繁1项集的集合。该集合记作L1.然后,L1用于找频繁2项集的集合L2,L2用于找L3,如此迭代,直到不能再找到频繁k项集。找每个Lk需要一次数据库全扫描。
I1 I2 I4
I1 I3
I1 I2 I3 I5
I1 I2 I3
I2 I5
I2 I3 I4
I3 I4
对于数据集,取最小支持度min_sup=2,最小置信度min_conf=0.8。
2、算法步骤
①首先单趟扫描数据集,计算各个一项集的支持度,根据给定的最小支持度闵值,得到一项频繁集L1。
②然后通过连接运算,得到二项候选集,对每个候选集再次扫描数据集,得出每个候选集的支持度,再与最小支持度比较。得到二项频繁集L2。
③如此进行下去,直到不能连接产生新的候选集为止。
④由频繁项集产生关联规则,关联规则产生步骤如下:
1)对于每个频繁项集l,产生其所有非空真子集;
2)对于每个非空真子集s,如果support_count(l)/support_count(s)>=min_conf,则输出s->(l-s),其中,min_conf是最小置信度阈值。
int countL2[10]; //各二维频繁子集出现的次数
char curL2[20][3]; //出现的二维子集
int countL3[10]; //各三维频繁子集出现的次数
char curL3[20][4]; //出现的三维子集
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];
k=0;
for(i=0;i<50;i++)
{
if(cur[i]==0)
break;
s=cur[i];
for(i=0;i<20;i++)
{
curL2[i][0]=0;
curL2[i][1]=0;
curL2[i][2]=0;
}
for(i=0;i<10;i++)
countL2[i]=0;
for(k=0;k<10;k++)
{
s=*(p+k);
if(SizeStr(s)<2)
continue;
for(i=0;i<SizeStr(s);i++)
for(j=i+1;j<SizeStr(s);j++)
{
if(*(s+j)==0)
break;
*(cur[n]+0)=*(s+i);
*(cur[n]+1)=*(s+j);
*(cur[n]+2)=0;
*(cur[n]+3)=0;
n++;
}
}
}
7)通过void LoadItemL2(char **p)得到各个2元频繁子串出现的次数
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL3[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL3[k][0]=cur[i][0];
curL3[k][1]=cur[i][1];
curL3[k][2]=cur[i][2];
curL3[k][3]=cur[i][3];
void LoadItemL2(char **p)
{
int k,i,j;
char* s;
int f;
SubItem2(p);
curL2[0][0]=cur[0][0];
curL2[0][1]=cur[0][1];
curL2[0][2]=cur[0][2];
k=0;
for(i=0;i<50;i++)
{
for(m=0;m<10;m++)
{
s=*(p+m);
if(SizeStr(s)<3)
continue;
for(i=0;i<SizeStr(s);i++)
for(j=i+1;j<SizeStr(s);j++)
{
for(h=j+1;h<SizeStr(s);h++)
{
if(*(s+h)==0)
break;
Return true;
Return false;
四、实验要求
1、数据集具有一定的代表性,可以使用数据库技术管理
2、最小支持度和置信度可以设置
3、实现界面友好
4、提交实验报告:实验题目、目的、数据集描述、实验环境、过程、结果和分析等。
五、实验步骤
1、所采用的数据集
I1 I2 I5
I1 I2
I2 I4
{
if(cur[i]==0)
break;
s=cur[i];
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL1[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL1[k][0]=cur[i][0];
curL1[k][1]=cur[i][1];
}
}
for(i=0;i<20;i++)
If((l1[1]=l2[1])&&( l1[2]=l2[2])&&........
&& (l1[k-2]=l2[k-2])&&(l1[k-1]<l2[k-1])) then{
c=l1连接l2 //连接步:产生候选
if has_infrequent_subset(c,Lk-1) then
delete c; //剪枝步:删除非频繁候选
void LoadItemL1(char **p)
{
int i,j,n=0,k=0;
char ch;
char* s;
int f;
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++)
3、程序实现
1)首先要在工程名文件夹里自己定义date.txt文档存放数据,然后在main函数中用FILE* fp=fopen("date.txt","r");将数据导入算法。
2)定义int countL1[10];找到各一维频繁子集出现的次数。
定义char curL1[20][2];实现出现的一维子集。
for(j=0;j<50;j++)
{
char* m;
m=curL1[i];
if(*m==0)
break;
if(OpD(m,cur[j]))
countL1[i]++;
}
printf("L1: \n ");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL1[i]==0)
*(cur[n]+0)=*(s+i);
*(cur[n]+1)=*(s+j);
*(cur[n]+2)=*(s+h);
*(cur[n]+3)=0;
n++;
}
}
}
}
9)同样我们要得到得到各个3元频繁子串出现的次数
void LoadItemL3(char** p)
{
int k,i,j;
char* s;
int f;
countL1[j]=0;
for(i=0;i<10;i++)
for(j=0;j<4;j++)
{
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;
for(i=0;i<50;i++)
break;
if(countL1[i]>=2)
printf("{I%s}: %d\n",curL1[i],countL1[i]);
}
}
6)通过void SubItem2(char **p)得到所有的2元子串
void SubItem2(char **p)
{
int i,j,k,n=0;
char* s;
memset(cur,0,sizeof(cur));
break;
if(countL3[i]>=2)
printf("{I%c,I%c,I%c}: %d\n",curL3[i][0],curL3[i][1],curL3[i][2],countL3[i]);
实验一频繁模式挖掘算法(Apriori)
一、实验目的
1、理解频繁模式和关联规则
2、掌握频繁模式挖掘算法Apriori
3、为改进Apriori打下基础
二、实验内容
1、选定一个数据集(可以参考教学中使用的数据集)
2、选择合适的实现环境和工具实现算法,本次试验采用的是C++
3、根据设置的最小支持度和置信度,给出数据集的频繁模式集
Apriori性质:频繁项集的所有非空子集也必是频繁的。Apriori算法主要包括连接步和剪枝步两步组成。在连接步和剪枝步中采用Apriori性质可以提高算法的效率。
Apriori伪代码
算法:Apriori
输入:D -事务数据库;min_sup -最小支持度计数阈值
输出:L - D中的频繁项集
方法:
int i,j,h,m;
int n=0;
memset(cur,0,sizeof(cur));
for(j=0;j<20;j++)
{
curL3[j][0]=0;
curL3[j][1]=0;
curL3[j][2]=0;
curL3Байду номын сангаасj][3]=0;
}
for(i=0;i<10;i++)
countL3[i]=0;
For each候选c属于Ct
c.count++;
}
Lk={c属于Ck | c.count>=min_sup}
}
Return L=所有的频繁集;
Procedure apriori_gen(Lk-1:frequent(k-1)-itemsets)
For each项集l1属于Lk-1
For each项集l2属于Lk-1
if(cur[i]==0)
break;
s=cur[i];
f=1;
for(j=0;j<=k;j++)
{
if(OpD(s,curL2[j]))
{
f=0;
break;
}
}
if(f==1)
{
++k;
curL2[k][0]=cur[i][0];
curL2[k][1]=cur[i][1];
curL2[k][2]=cur[i][2];
L1=find_frequent_1-itemsets(D); //找出所有频繁1项集
For(k=2;Lk-1!=null;k++){
Ck=apriori_gen(Lk-1); //产生候选,并剪枝
For each事务t in D{ //扫描D进行候选计数
Ct =subset(Ck,t); //得到t的子集
char cur[50][4];
3)定义int SizeStr(char* m)得到字符串的长度。实现代码如下:
int SizeStr(char* m)
{
int i=0;
while(*(m+i)!=0)
{
i++;
}
return i;
}
4)比较两个字符串,如果相等返回true,否则返回false
bool OpD(char* x,char* y)
else add c to Ck;
}
Return Ck;
Procedure has_infrequent_sub(c:candidate k-itemset; Lk-1:frequent(k-1)-itemsets)
For each(k-1)-subset s of c
If s不属于Lk-1 then
break;
if(countL2[i]>=2)
printf("{I%c,I%c}: %d\n",curL2[i][0],curL2[i][1],countL2[i]);
}
}
8)通过定义void SubItem3(char **p)得到所有3元的子串
void SubItem3(char **p)
{
char *s;
{
int i=0;
if(SizeStr(x)==SizeStr(y))
{
while(*(x+i)==*(y+i))
{
i++;
if(*(x+i)==0 && *(y+i)==0)
return true;
}
}
return false;
}
5)通过void LoadItemL1(char **p)得到所有1元的字串和各自出现的次数
}
}
for(i=0;i<20;i++)
for(j=0;j<50;j++)
{
s=curL2[i];
if(*s==0)
break;
if(OpD(s,cur[j]))
countL2[i]++;
}
printf("L2: \n");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL2[i]==0)
}
}
for(i=0;i<20;i++)
for(j=0;j<50;j++)
{
s=curL3[i];
if(*s==0)
break;
if(OpD(s,cur[j]))
countL3[i]++;
}
printf("L3: \n");
printf("项集支持度计数\n");
for(i=0;i<10;i++)
{
if(curL3[i]==0)
三、实验原理
该算法的基本思想是:Apriori使用一种称作逐层搜索的迭代方法,k项集用于探索(k+1)项集。首先,通过扫描数据库,累积每个项的计数,并收集满足最小支持度的项,找出频繁1项集的集合。该集合记作L1.然后,L1用于找频繁2项集的集合L2,L2用于找L3,如此迭代,直到不能再找到频繁k项集。找每个Lk需要一次数据库全扫描。
I1 I2 I4
I1 I3
I1 I2 I3 I5
I1 I2 I3
I2 I5
I2 I3 I4
I3 I4
对于数据集,取最小支持度min_sup=2,最小置信度min_conf=0.8。
2、算法步骤
①首先单趟扫描数据集,计算各个一项集的支持度,根据给定的最小支持度闵值,得到一项频繁集L1。
②然后通过连接运算,得到二项候选集,对每个候选集再次扫描数据集,得出每个候选集的支持度,再与最小支持度比较。得到二项频繁集L2。
③如此进行下去,直到不能连接产生新的候选集为止。
④由频繁项集产生关联规则,关联规则产生步骤如下:
1)对于每个频繁项集l,产生其所有非空真子集;
2)对于每个非空真子集s,如果support_count(l)/support_count(s)>=min_conf,则输出s->(l-s),其中,min_conf是最小置信度阈值。