Aprior算法的实现

来源:互联网 发布:安卓自动接听软件 编辑:程序博客网 时间:2024/05/29 14:16

        终于把Aprior的算法过程看懂了,Aprior算法的原理其实很简单,但是当真正写起代码来还是比较麻烦,在百度文库了,下了一个C++版的Aprior算法,用来研究。

       算法思想:1,先对样本数据,用二维数组保存。2,找一元频繁集,先遍历一下样本数组,保存成一列的形式cur[n][],然后再扫描那一列,提取不重复元素保存起来curL1[][],再次遍历样本列,把每个不重复元素的个数记录下来,也就是CountL1[],3找二元频繁集,for循环数组,对每一行分析:对其中元素进行排列组成成2元形式,进行保存cur[n][],提取不重复元素保存起来curL2[][],再次遍历样本列,把每个不重复元素的个数记录下来,也就是CountL2[],3,三元,四元类似分析.....4,关联规则:先是通过支持度删选,对于已经满足条件的三元数据进行分析,对三元数据求其真子集,然后对子集中长度为1,和长度为2的组合求其置信率;5,最后对其进行筛选。

算法源码:(参考别人的代码)

//支持度不小于2,置信度不小于0.8#include "stdio.h"#include "iostream.h"#include "string.h"//定义全局变量char curL1[20][2];//实现出现的一维子集int countL1[10];//找到各一维频繁子集出现的次数。char curL2[20][3];  //出现的二维子集int countL2[10];    //各二维频繁子集出现的次数char curL3[20][4];  //出现的三维子集int countL3[10];    //各三维频繁子集出现的次数char cur[50][4];//临时二维数组,用于保存中间产生的变量//定义int SizeStr(char* m) 得到字符串的长度。实现代码如下:int SizeStr(char* m){int i=0;while(*(m+i)!=0){i++;}return i;}//比较两个字符串,如果相等返回true,否则返回falsebool OpD(char* x,char* y){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;}//通过void LoadItemL1(char **p) 得到所有1元的字串和各自出现的次数void LoadItemL1(char **p)//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++)countL1[j]=0;//将样本数组中的数值提取出来,保存在cur[n][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;//printf("%c",cur[n][0]);n++;}}//printf("\n");curL1[0][0]=cur[0][0];curL1[0][1]=cur[0][1];k=0;//放篮子:将cur[n][0]中数据不重复的放入curL1中for(i=0;i<50;i++){if(cur[i]==0)break;s=cur[i];f=1;for(j=0;j<=k;j++){if(OpD(s,curL1[j]))//与已经放入curL1集合的字符做比较{f=0;break;}}if(f==1){++k;curL1[k][0]=cur[i][0];curL1[k][1]=cur[i][1];}}//for(i=0;i<=k;i++)//{//printf("%c",curL1[i][0]);//}//printf("\n");//curL1[]已经把数提取出来,根据curL1[]值查找cur[n][],对比,计数(就是支持度)for(i=0;i<20;i++){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)break;if(countL1[i]>=2)printf("{I%s}:       %d\n",curL1[i],countL1[i]);}}//通过void SubItem2(char **p) 得到所有的2元子串void SubItem2(char **p){int i,j,k,n=0;char* s;memset(cur,0,sizeof(cur));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;//如果字符串长度小于2,跳出本次循环//每个事务的ID都进行组合,例如1,2,5可以形成:12(cur[0]),15(cur[1]),25(cur[2])//提取二元,就需要二层循环,三元,则三层循环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;printf("%c%c\n",*(cur[n]+0),*(cur[n]+1));n++;}}}//结果得到的cur[][]数组是排列组合项,里面有很多重复项}//通过void LoadItemL2(char **p) 得到各个2元频繁子串出现的次数void LoadItemL2(char **p){int k,i,j;char* s;int f;SubItem2(p);//curL2就相当于一个篮子(集合),先把12组合放进去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++){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];}}//将cur[][]精简就得到curL2[][],里面没有重复的二元元素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)break;if(countL2[i]>=2)printf("{I%c,I%c}:       %d\n",curL2[i][0],curL2[i][1],countL2[i]);}}//通过定义void SubItem3(char **p) 得到所有3元的子串void SubItem3(char **p){char *s;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(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;*(cur[n]+0)=*(s+i);*(cur[n]+1)=*(s+j);*(cur[n]+2)=*(s+h);*(cur[n]+3)=0;n++;}}}}}//⑨同样我们要得到得到各个3元频繁子串出现的次数void LoadItemL3(char** p){int k,i,j;char* s;int f;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];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];}}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)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]);}}//⑩定义void LoadItemL4(char** p) 得到各个3元子串出现的次数void LoadItemL4(char** p){int i;char* s;int j=0;for(i=0;i<10;i++){s=*(p+i);if(SizeStr(s)==4)j++;}printf("四维子集出现的次数:  %d\n",j);printf("没有四维的频繁子集,算法结束! \n");}//11通过void Support(char* w,int g) 得到关联规则,并输出结果void Support(char* w,int g){printf("Support\n");int i,j,k,n=0;char* s;float c=0.8,d=0;memset(cur,0,sizeof(cur));s=w;for(i=0;i<SizeStr(s);i++){*(cur[n]+0)=*(s+i);//cur[0][0]=1;cur[1][0]=2;cur[2][0]=5;*(cur[n]+1)=0;*(cur[n]+2)=0;*(cur[n]+3)=0;n++;}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[3][0]=1;cur[3][1]=2;cur[4][0]=1;cur[4][1]=5;cur[5][0]=2;cur[5][1]=5;*(cur[n]+1)=*(s+j);*(cur[n]+2)=0;*(cur[n]+3)=0;n++;}}for(i=0;i<10;i++){if(SizeStr(cur[i])==1)//字符串长度为1{for(j=0;j<10;j++){if(OpD(cur[i],curL1[j])){d=countL3[g]/(float)countL1[j];//if(d>=c)printf("{I%s}:    %f\n",curL1[i],d);//break;}}}if(SizeStr(cur[i])==2)//字符串长度为2{for(j=0;j<10;j++){if(OpD(cur[i],curL2[j])){d=countL3[g]/(float)countL2[j];if(d>=c)printf("{I%c,I%c}:    %f \n",curL2[j][0],curL2[j][1],d);break;}}}}}//12最后通过main函数完成整过程序int main(){int i=0,j=0,k;char buf[10][6];//保存样本char* p[10];//等价于buf[10][6],自己换成了数组指针的形式memset(buf,0,sizeof(buf));//申请内存空间/*FILE* fp=fopen("date.txt","r");if(fp==NULL)return 0;ch=fgetc(fp);while(ch!=EOF){printf("adf");if(ch==0xa || ch==0xd){i++;ch=fgetc(fp);j=0;continue;}buf[i][j]=ch;j++;ch=fgetc(fp);}*/buf[0][0]='1';buf[0][1]='2';buf[0][2]='5';buf[1][0]='1';buf[1][1]='2';buf[2][0]='2';buf[2][1]='4';buf[3][0]='1';buf[3][1]='2';buf[3][2]='4';buf[4][0]='1';buf[4][1]='3';buf[5][0]='1';buf[5][1]='2';buf[5][2]='3';buf[5][3]='5';buf[6][0]='1';buf[6][1]='2';buf[6][2]='3';buf[7][0]='2';buf[7][1]='5';buf[8][0]='2';buf[8][1]='3';buf[8][2]='4';buf[9][0]='3';buf[9][1]='4';for(k=0;k<10;k++){*(p+k)=buf[k];}LoadItemL1(p);LoadItemL2(p);LoadItemL3(p);LoadItemL4(p);printf("产生关联规则: \n");printf("非空子集:    置信度:\n");for(i=0;i<10;i++){//printf("{%c,%c,%c}:       %d\n",curL3[i][0],curL3[i][1],curL3[i][2],countL3[i]);//printf("%s\n",curL3[i]);if(curL3[i]!=0 && countL3[i]>=2)Support(curL3[i],i);}return 0;}

运行结果:

原创粉丝点击