首页 > 代码库 > 数据挖掘算法 Apriori 例子+源码

数据挖掘算法 Apriori 例子+源码

 

转自这里

Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。其核心是基于
两阶段频集思想的递推算法。该关联规则在分类上属于单维、单层、布尔关联规
则。在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集。

由Agrawal等人提出的Apriori是经典的关联规则和频繁项集挖掘算法,围绕着它的改进和实现有大量的文献。该算法是挖掘产生布尔关联规则频繁项目集的经典算法,从其产生到现在对关联规则挖掘方面的研究有着很大的影响。

为了提高频繁项目的挖掘效率,Apriori算法利用了两个重要的性质,用于压缩搜索的空间。

【1】若X为频繁项目集,则X的所有子集都是频繁项目集。

【2】若X为非频繁项目集,则X的所有超集均为非频繁项目集。

Apriori算法的处理流程为:宽度优先搜索整个项集空间,从k=0开始,迭代产生长度为k+1的候选项集的集合Ck+1。候选项集是其所有子集都是频繁项集的项集。C1I0中所有的项构成,在第k层产生所有长度为k+1的项集。这由两步完成:第一步,Fk自连接。将Fk中具有相同(k-1)-前缀的项集连接成长度为k的候选项集。第二步是剪枝,如果项集的所有长度为k的子集都在Fk中,该项集才能作为候选项集被加入Ck+1中。为了计算所有长度为k的候选项集的支持度,在数据库水平表示方式下,需要扫描数据库一遍。在每次扫描中,对数据库中的每条交易记录,为其中所包含的所有候选k-项集的支持度计数加1。所有频繁的k-项集被加入Fk中。此过程直至Ck+1等于空集时结束。

算法  AprioriInput:          Transaction DataBase D,Minimum support threshold minsup。Output:      Frequent pattern L(1) L1=search_frequent_1-itemsets( D );(2) for(k=2;Lk-1≠φ;k++) do(3) begin(4)    Ck=apriori-gen(Lk-1);(5)    for all transactions t D do(6)    begin(7)      Ct=subset(Ck,t);(8)      for all candidates c Ct do(9)        c.count++;(10)    end(11)    Lk ={c Ck|c.count≥minsup}(12) end(13) Answer L=∪kLk;Procedure Search_frequent_1-itemsets( D )(1) begin(2)  for all transactions t D do(3)  begin(4)    for each item ik t do(5)      ik.count++;(6)  end(7)  L1 ={ i I | i.count≥minsup}(8)  return L1;(9) endProcedure apriori_gen(Lk)(1) begin(2)   for each itemset l1 Lk do(3)     for each itemset l2 Lk do(4)     begin(5)       if ( l1[1]=l2[1]) ( l1[2]=l2[2]) … ( l1[k-1]=l2[k-1]) ( l1[k]<l2[k]) then(6)       begin(7)          c= l1 l2;(8)          if Is_include_infrenquent_subset(c,Lk) then(9)             delete c;(10)         else add c to Ck+1 ;(11)       end(12)      end(13)    return Ck+1 ;(14) endProcedure Is_include_infrenquent_subset(c,Lk)(1)begin(2)  for each k-subset s of c(3)     if s Lk then(4)       reture TURE;(5)  return FALSE ;(6)end

在主程序中,第一步首先扫描整个交易数据库D,统计每个项目(item)的支持数,计算其支持度,将支持度大于等于最小支持度minsup的项目构成的集合放入到L1 中;从第2步到第11步,用k-1频繁项目集构成的Lk-1生成候选集的集合Ck,以便从中生成Lk,其中apriori_gen函数(第4步)用来从Lk-1中生成Ck,然后对数据库进行扫描(第5步),对于数据库中的每一个交易,subset函数用来发现此交易包含的所有候选集(第7步),并为这些候选集的计数器加1(第8-9步)。最后满足minsup的候选集被放入到Lk中。

apriori_gen过程完成两种操作:并(join)和剪枝(prune)。在并运算步骤中,Lk-1 Lk-1 进行并运算生成潜在的候选集(2-7步),条件l1[k-1]<l2[k-1]保证不会有重复的候选集生成(第5步)。在剪枝步骤中(8-10步),利用性质2.1,删除那些存在子集不是频繁项目集的候选集,测试子集是否为频繁项目集由过程Is_include_infrenquent_subset完成。

为了清楚的阐述Apriori算法的挖掘过程,现举例如下:

【例1设事务数据库D如表2.1所示,D中包含4个事务,即|D|=4,最小支持数mincount=2,即最小支持度minsup=2/4=50%。挖掘频繁项目集的具体过程如下所述:C1={{A},{B},{C},{D},{F}},第一次循环产生L1={{A},{B},{C},{F}},由Apriori_gen(L1)生成C2,扫描数据库,计算C2中每个候选集得到L2。依此循环,得到L3。整个挖掘过程如图2.1所示。

表1 事务数据库D

Tid

事务

100

200

300

400

B,C,F

A,C,D

B,F

A,B,C,F

  

 

图1 Apriori算法的执行过程

在找到了事务数据库中的所有频繁项集后,利用这些频繁项集可以产生关联规则,产生关联规则的步骤如下:

(1) 对于每个频繁项目集l,产生l的所有非空子集。

(2) 对于l的每个非空子集m,如果support(l)/support(m)≥minconf,则输出规则“m (l-m)”。

例如,在上例中产生的频繁项目集l={B,C,F},l的非空子集有{B,C}、{B,F}、{C,F}、{B}、{C}和{F},则运用上述产生关联规则的方法可以得到以下关联规则:

          B C F    confidence=(2/4)/(4/4)=1

          B F C    confidence=(2/4)/(3/4)=0.667

          C F B    confidence=(2/4)/(2/4)=1

          F B C    confidence=(2/4)/(3/4)= 0.667

          C B F    confidence=(2/4)/(3/4)= 0.667

          B C F    confidence=(2/4)/(3/4)= 0.667

 

  1 源代码  apriori.c  2   3 //////////////////////////////////////////////////////////////////////////  4 /*  5 *  6 *  7 *  8 * 文件名称:apriori.c  9  10 * 11 * 摘 要:apriori的最简单实现 12  13 * 14 * 当前版本:1.0 15 * 完成日期:2006.05 16 * 17 *///////////////////////////////////////////////////////////////////////// 18  19 #include<stdio.h> 20 typedef  struct 21 { 22 int item[100];  //数据项 23 } D_Node;      //数据库D 24  25  26 typedef  struct 27 { 28 int item[100];  //数据项,用item[0]保存支持度 29  30 } C_Node; //候选集 31  32 typedef  struct 33 { 34 int item[100];  //数据项,用item[0]保存支持度 35 } L_Node;//频繁集 36  37 C_Node C[100][100]; 38 L_Node L[100][100]; 39 D_Node D[100]; 40  41 int min_supp;  //最小支持度 42  43   44  45 void  InPut() 46 { 47  int i,j,n,n1; 48  printf("请输入最小支持度:"); 49  scanf("%d",&min_supp); 50   printf("请输入交易集的大小"); 51   scanf("%d",&D[0].item[0]); 52   n=D[0].item[0]; 53  54      for(i=1;i<=n;i++)  //for1 55      {   56         printf("请输入交易[%d]中记录的个数(n)",i); 57          scanf("%d",&n1); 58          D[i].item[0]=n1; 59  60            for(j=1;j<=n1;j++)  //for2 61            { 62               printf("请输入交易[%d]中记录项,直接输入数字:",i); 63               scanf("%d",&D[i].item[j]);                   64            }//for2 65                  66            }  //for1 67      68      }//end of InPut 69  70  71 void  C1() 72 { 73  //功能:扫描数据集D生成1项候选集C1 74  //输入:数据集D 75  //输出1项候选集C1 76  //初始条件 数据集D 非空 77    int i,j,k; 78    int no=1,temp=0; 79    C[1][0].item[0]=0;  //1 项集的个数,在本算法中,用C[n][k].item[0]来保存候选集Cn的第k项的支持度 80    if(D[0].item[0]!=0) 81    {  82       C[1][1].item[1]=D[1].item[1]; 83           84    } 85       86     for(i=1;i<=D[0].item[0];i++)  //for1  87     { 88    89          for(j=1;j<=D[i].item[0];j++)  //for2   90       { 91                temp=1; 92                for(k=1;k<=no;k++)  //for3 93       { 94                   if(C[1][k].item[1]==D[i].item[j]) 95             { 96                      C[1][k].item[0]++;  //支持度加1 97                       temp=0;  // 98                            99                   }   //if100 101                }//end for3102            103          104               if(temp)//生成新的项集105            {106                     C[1][++no].item[1]=D[i].item[j];107                     C[1][no].item[0]=1;    108            }109       110          }//end for2111   112     } // end  for1113 114     C[1][0].item[0]=no;//数据项的个数 115 116 }  //end of  C1()117 118 119 void Cn( int n)120 { 121  //用频繁集Ln-1为基础,通过连接得到n项候选集Cn122  123  int i,j,k,p,q,s,t,num;124  int no=0,temp=0,count;125 126  C[n][0].item[0]=0;  //初始化127 128 //printf("in Cn(%d) n=%d/n",n,n);129 //printf("in Cn(%d) C[%d][0].item[0]=%d/n",n,n,C[n][0].item[0]);130 131 num=L[n-1][0].item[0];  //num是Ln-1项集的数据个数132 133    for(i=1;i<=num;i++) 134   135       for(j=i+1;j<=num;j++)   //for2136          {137   138       temp=1;  //测试是否满足联结条件139               if(n>2)//if 1140               {141                   for(k=1;k<n-1;k++)     //for3  142                  {143       if(L[n-1][i].item[k]!=L[n-1][j].item[k])144                    {  temp=0;145                      break; }//if 1146 147                     }//end for3148 149                  }//end if1150 151                       if(temp==1)//满足联结条件152                      {153                           // printf("in if 2  no=%d/n",no);154                      no++;155 156                     for(p=1;p<=n-1;p++) 157                     C[n][no].item[p]=L[n-1][i].item[p];158                     C[n][no].item[p]=L[n-1][j].item[p-1];159                     C[n][no].item[0]=0;160                          for(q=1;q<=D[0].item[0];q++)  //for5  测试其支持度161 162        {   163        164         count=0; //count用来记数,当所测试的项存在时,count加1,当count=n时,则子集存在165 166                                for(s=1;C[n][no].item[s]!=0;s++)  //for6167                           {168                                       for(t=1;t<=D[q].item[0];t++)  //for7169            {170                                              if(C[n][no].item[s]==D[q].item[t])171 172             {   count+=1;173                       break;174             }175            }//end for7176                                     177           }//end for 6178                            if(count==n) C[n][no].item[0]+=1;//子集存在,第no项的支持度加1179                   180        }//end for5181                           182                           183                       C[n][0].item[0]+=1;184        }//end if2185            }//end for2186 187      /* num=C[n][0].item[0];188      printf("in Cn(%d) num=%d/n",n,num);189    for(i=1;i<=num;i++)190     for(j=0;j<=n;j++)191     {192      printf("in Cn(%d) C[%d][%d].item[%d]=%d/n",n,n,i,j,C[n][i].item[j]);193     }194    printf("in Cn(%d) C[%d][0].item[0]=%d/n",n,n,C[n][0].item[0]);  */195   196 }//end of Cn()197 198 void L1()199 {  200     int i,j,k;201  j=0;202    L[1][0].item[0]=0;203   204    //printf("C[1][0].item[0]=%d/n",C[1][0].item[0]);205 206    for(i=1;i<=C[1][0].item[0];i++)207    {   208        if(C[1][i].item[0]>=min_supp)209        {210        j+=1;211         for(k=1;k<=1;k++)212          L[1][j].item[k]=C[1][i].item[k];213         L[1][j].item[0]=C[1][i].item[0];214  // printf("L[1][%d].item[1]=%d   ",j,L[1][j].item[1]);  测试功能时加的215  // printf("  -------------%d/n",L[1][j].item[0]);216   217        }218    }//end for1219    L[1][0].item[0]=j;220 }//end of L1()221 222 void Ln(int n)223 {  224     int i,j,k;225  Cn(n);226     j=0;227     L[n][0].item[0]=0;228 229    // printf("in Ln(%d) C[%d][0].item[0]=%d/n",n,n,C[n][0].item[0]);230 231    for(i=1;i<=C[n][0].item[0];i++)  //for 1232    {233        if(C[n][i].item[0]>=min_supp)234        {235          j+=1;236         for(k=1;k<=n;k++)237          L[n][j].item[k]=C[n][i].item[k];238         L[n][j].item[0]=C[n][i].item[0]; 239        }  //end if240 241 242    }//end for1243 244    /*  for(i=1;i<=j;i++)245        for(k=0;k<=n;k++)246   {printf("L[%d][%d].item[%d]=%d /n",n,i,k,L[n][i].item[k]);247   248   }   */249 250 L[n][0].item[0]=j; //保存数据的个数251 252 }//end of Ln(int n)253 254 255   void  OutPut(int n)256   {257      int i,j,k;258      printf("频繁项目集L%d如下:/n",n);259      k=L[n][0].item[0];260          if(k!=0)261          {262              for(i=1;i<=k;i++)263           {264                 printf("{");265                for(j=1;j<=n;j++)     266         printf("  I%d ",L[n][i].item[j]);267         printf("}        支持度:%d/n",L[n][i].item[0]);268           269       270              }//for271            272           }273          else                printf("项目集为空/n");274           275      276   }277 278 279   void main()280   {281  int i;282  int n=1;283     InPut();284  C1();//初始化,生成1项候选集C1285  L1();//得到1项频繁集L1286     while(L[n][0].item[0]!=0)287  {288   n+=1;289         Ln(n);290  }291     for(i=1;i<=n;i++)292         OutPut(i);293 294  char ch;295    scanf("%d",&i);296  297   }298 299  300 301  302 303 --------------------------------------------------------------------------------------304 305 FAST apriori.cpp306 307 //////////////////////////////////////////////////////////////////////////308 /*309 *310 *311 *312 * 文件名称:FAST apriori.cpp313 314 *315 * 摘 要:采用位运算提高算法的效率316 317 *318 * 当前版本:1.0319 320 * 完成日期:2006.06.20321 *322 */////////////////////////////////////////////////////////////////////////323 324 #include <stdio.h>325 #include <string.h>326 327 typedef  struct328 {329 char item[10];  //数据项330 int min_supp_count;//最小支持度数331 } C_Node;      //候选集332 333 334 typedef  struct335 {336 char item[10];  //数据项337 int min_supp_count;//最小支持度数338 } L_Node;     //频繁集339 340 char D[10][10];341 L_Node L[100];342 C_Node C[100];343 int min_supp_count=2;344 int num=100;345 void  InPut()346 {347 348  strcpy(D[1],"abe");349  strcpy(D[2],"bd");350  strcpy(D[3],"bc");351  strcpy(D[4],"abd");352  strcpy(D[5],"ac");353  strcpy(D[6],"bc");354  strcpy(D[7],"ac");355  strcpy(D[8],"abce");356  strcpy(D[9],"abc");357 358  359 }//end of InPut360 int  * DB=new int[num];361 362  363 364 void suppDB()365 {366   int m=e;367   int n;368   int k;369   for (int i=1;i<=9;i++)370   {371    n=strlen(D[i]);372    DB [i]=0;373    for (int j=0;j<n;j++)374    {375     k=1;376     DB [i]+=k<<(int)(m-D[i][j]); 377    } 378   }379 380  381 382 }383 384 void check_supp(int num,int no)385 {386 int i,j,k,m;387     int check;388    m=e;389   390      for(i=1;i<=num;i++)391   {    check=0;392        C[i].min_supp_count=0;393        for (j=0;j<no;j++)394     {395    k=1;396    check+=(int)(k<<(m-C[i].item[j]));397       }398    for (j=1;j<=9;j++)399    {400     if (check==(check&DB[j]))401     {402       C[i].min_supp_count+=1;//子集存在,支持度数加1403     }404    }405   }406 407 }408 409 void  C1()410 {411  //功能:扫描数据集D生成1项候选集C1412  //输入:数据集D413  //输出1项候选集C1414  //初始条件 数据集D 非空415  strcpy(C[1].item,"a");416  strcpy(C[2].item,"b");417  strcpy(C[3].item,"c");418  strcpy(C[4].item,"d");419  strcpy(C[5].item,"e");420   421    C[0].min_supp_count=5;  //1 项候选集的个数,在本算法中,用C[0].min_supp_count来保存候选集Cn的个数  422 423   check_supp(5,1);424  425   426  }  //end of  C1()427 428 429 void Cn( int n)430 { 431  //用频繁集Ln-1为基础,通过连接得到n项候选集Cn432  433  int i,j,k,p,num;434  int no=0,temp=0;435 436  C[0].min_supp_count=0;  //初始化437 438 439 num=L[0].min_supp_count;  //num是Ln-1项集的数据个数440 441    for(i=1;i<=num;i++) 442   443       for(j=i+1;j<=num;j++)   //for2444          {445   446       temp=1;  //测试是否满足联结条件447               if(n>2)//if 1448               {449                   for(k=0;k<n-2;k++)     //for3  450                  {451       if(L[i].item[k]!=L[j].item[k])452                    {  temp=0;453                      break; }//if 1454 455                     }//end for3456 457                  }//end if1458 459                       if(temp==1)//满足联结条件460                      {461                           // printf("in if 2  no=%d/n",no);462                      no++;463 464                     for(p=0;p<=n-2;p++) 465                     C[no].item[p]=L[i].item[p];466                     C[no].item[p]=L[j].item[p-1];467                     C[no].min_supp_count=0;468                     C[0].min_supp_count+=1;469        }//end if2470            }//end for2471 num=C[0].min_supp_count;472    check_supp(num,n);//测试支持度473 }//end of Cn() 474 475 476 void L1()477 {   int n=1;478     int i,j,k;479  j=0;480    L[0].min_supp_count=0;//频繁集的个数,初始为0481    482    for(i=1;i<=C[0].min_supp_count;i++)483    {   484        if(C[i].min_supp_count>=min_supp_count)485        {486        j+=1;487         strcpy(L[j].item,C[i].item);  488   L[j].min_supp_count=C[i].min_supp_count;489        }490    }//end for1491    L[0].min_supp_count=j;///频繁集的个数,最后为j个492 493     printf("频繁项目集L%d如下:/n",n);494      k=L[0].min_supp_count;495          if(k!=0)496          {497              for(i=1;i<=k;i++)498           {499                 printf("{");500                for(j=0;j<n;j++)     501         printf("  %c ",L[i].item[j]);502         printf("}        支持度:%d/n",L[i].min_supp_count);503           504       505              }//for506            507           }508          else                printf("项目集为空/n");509 510 }//end of L1()511 512 void Ln(int n)513 {  514     int i,j,k;515  Cn(n);516     j=0;517     L[0].min_supp_count=0;518 519   520    for(i=1;i<=C[0].min_supp_count;i++)  //for 1521    {522        if(C[i].min_supp_count >=min_supp_count)523        {524          j+=1;525         strcpy(L[j].item,C[i].item);  526   L[j].min_supp_count=C[i].min_supp_count;527          528        }  //end if529 530 531    }//end for1532 533   534 535 L[0].min_supp_count=j; //保存数据的个数536  printf("频繁项目集L%d如下:/n",n);537      k=L[0].min_supp_count;538          if(k!=0)539          {540              for(i=1;i<=k;i++)541           {542                 printf("{");543                for(j=0;j<n;j++)     544         printf("  %c ",L[i].item[j]);545         printf("}        支持度:%d/n",L[i].min_supp_count);546           547       548              }//for549            550           }551          else                printf("项目集为空/n");552 553 }//end of Ln(int n)554 555 556  void main()557 {558 559   560       int n=1;561     InPut();562  suppDB();563  C1();//初始化,生成1项候选集C1564  L1();//得到1项频繁集L1565   while(L[0].min_supp_count!=0)566  {567   n+=1;568         Ln(n);569   }570   char ch;571   printf("press any key to eixe/n");572   scanf("%c",&ch);573   574    }

 Java代码

  1 import java.io.BufferedWriter;  2 import java.io.FileWriter;  3 import java.util.*;  4   5   6 public class Apriori {  7   8  private double minsup = 0.6;// 最小支持度  9  private double minconf = 0.2;// 最小置信度 10  11  // 注意使用IdentityHashMap,否则由于关联规则产生存在键值相同的会出现覆盖 12  private IdentityHashMap ruleMap = new IdentityHashMap(); 13  14  private String[] transSet = { "abc", "abc", "acde", "bcdf", "abcd", "abcdf" };// 事务集合,可以根据需要从构造函数里传入 15  16  private int itemCounts = 0;// 候选1项目集大小,即字母的个数 17  private TreeSet[] frequencySet = new TreeSet[40];// 频繁项集数组,[0]:代表1频繁集... 18  private TreeSet maxFrequency = new TreeSet();// 最大频繁集 19  private TreeSet candidate = new TreeSet();// 1候选集 20  private TreeSet candidateSet[] = new TreeSet[40];// 候选集数组 21  private int frequencyIndex; 22  23   24  public Apriori() { 25  26   maxFrequency = new TreeSet(); 27   itemCounts = counts();// 初始化1候选集的大小 28  29   // 初始化其他两个 30   for (int i = 0; i < itemCounts; i++) { 31    frequencySet[i] = new TreeSet(); 32    candidateSet[i] = new TreeSet(); 33   } 34   candidateSet[0] = candidate; 35  } 36  37   38  public Apriori(String[] transSet) { 39   this.transSet = transSet; 40   maxFrequency = new TreeSet(); 41   itemCounts = counts();// 初始化1候选集的大小 42  43   // 初始化其他两个 44   for (int i = 0; i < itemCounts; i++) { 45    frequencySet[i] = new TreeSet(); 46    candidateSet[i] = new TreeSet(); 47   } 48   candidateSet[0] = candidate; 49  } 50  51   52  public int counts() { 53  54   String temp1 = null; 55   char temp2 = ‘a‘; 56   // 遍历所有事务集String 加入集合,set自动去重了 57   for (int i = 0; i < transSet.length; i++) { 58    temp1 = transSet[i]; 59    for (int j = 0; j < temp1.length(); j++) { 60     temp2 = temp1.charAt(j); 61     candidate.add(String.valueOf(temp2)); 62    } 63   } 64   return candidate.size(); 65  } 66  67   68  public void item1_gen() { 69   String temp1 = ""; 70   double m = 0; 71  72   Iterator temp = candidateSet[0].iterator(); 73   while (temp.hasNext()) { 74    temp1 = (String) temp.next(); 75    m = count_sup(temp1); 76  77    // 符合条件的加入 1候选集 78    if (m >= minsup * transSet.length) { 79     frequencySet[0].add(temp1); 80    } 81   } 82  } 83  84   85  public double count_sup(String x) { 86   int temp = 0; 87   for (int i = 0; i < transSet.length; i++) { 88    for (int j = 0; j < x.length(); j++) { 89     if (transSet[i].indexOf(x.charAt(j)) == -1) 90      break; 91     else if (j == (x.length() - 1)) 92      temp++; 93    } 94   } 95   return temp; 96  } 97  98   99  public void canditate_gen(int k) {100   String y = "", z = "", m = "";101   char c1 = ‘a‘, c2 = ‘a‘;102 103   Iterator temp1 = frequencySet[k - 2].iterator();104   Iterator temp2 = frequencySet[0].iterator();105   TreeSet h = new TreeSet();106 107   while (temp1.hasNext()) {108    y = (String) temp1.next();109    c1 = y.charAt(y.length() - 1);110 111    while (temp2.hasNext()) {112     z = (String) temp2.next();113 114     c2 = z.charAt(0);115     if (c1 >= c2)116      continue;117     else {118      m = y + z;119      h.add(m);120     }121    }122    temp2 = frequencySet[0].iterator();123   }124   candidateSet[k - 1] = h;125  }126 127  // k候选集=>k频繁集128  public void frequent_gen(int k) {129   String s1 = "";130 131   Iterator ix = candidateSet[k - 1].iterator();132   while (ix.hasNext()) {133    s1 = (String) ix.next();134    if (count_sup(s1) >= (minsup * transSet.length)) {135     frequencySet[k - 1].add(s1);136    }137   }138  }139 140  public boolean is_frequent_empty(int k) {141   if (frequencySet[k - 1].isEmpty())142    return true;143   else144    return false;145  }146 147  public boolean included(String s1, String s2) {148   for (int i = 0; i < s1.length(); i++) {149    if (s2.indexOf(s1.charAt(i)) == -1)150     return false;151    else if (i == s1.length() - 1)152     return true;153   }154   return true;155  }156 157  public void maxfrequent_gen() {158   int i, j;159   Iterator iterator, iterator1, iterator2;160   String temp = "", temp1 = "", temp2 = "";161   for (i = 1; i < frequencyIndex; i++) {162    maxFrequency.addAll(frequencySet[i]);163   }164   // for (i = 0; i < frequencyIndex; i++) {165   // iterator1 = frequencySet[i].iterator();166   // while (iterator1.hasNext()) {167   // temp1 = (String) iterator1.next();168   // for (j = i + 1; j < frequencyIndex; j++) {169   // iterator2 = frequencySet[j].iterator();170   // while (iterator2.hasNext()) {171   // temp2 = (String) iterator2.next();172   // if (included(temp1, temp2))173   // maxFrequency.remove(temp1);174   // }175   // }176   // }177   // }178  }179 180  181  public void print_maxfrequent() {182   Iterator iterator = maxFrequency.iterator();183   System.out.print("产生规则频繁项集:");184   while (iterator.hasNext()) {185    System.out.print(toDigit((String) iterator.next()) + "\t");186   }187   System.out.println();188  }189 190  191  public void rulePrint() {192   String x, y;193   double temp = 0;194 195   Set hs = ruleMap.keySet();196   Iterator iterator = hs.iterator();197 198   StringBuffer sb = new StringBuffer();199   System.out.println("关联规则:");200   while (iterator.hasNext()) {201    x = (String) iterator.next();202 203    y = (String) ruleMap.get(x);204 205    temp = (count_sup(x + y) / count_sup(x));206    207    //x = toDigit(x);208    //y = toDigit(y);209 210    System.out.println(x + (x.length() < 5 ? "\t" : "") + "-->" + y211      + "\t" + temp);212    sb.append("  " + x + (x.length() < 5 ? "\t" : "") + "-->" + y213      + "\t" + temp + "\t\n");214   }215   BufferedWriter bw = null;216   try {217    FileWriter fw = new FileWriter("Asr.txt");218 219    bw = new BufferedWriter(fw);220 221    bw.write("最小支持度 minsup = " + minsup);222    bw.newLine();223    bw.write("最小置信度 minconf = " + minconf);224    bw.newLine();225    bw.write("产生关联规则如下: ");226    bw.newLine();227 228    bw.write(sb.toString());229    // bw.newLine();230 231    if (bw != null)232     bw.close();233   } catch (Exception e) {234    e.printStackTrace();235   }236 237  }238 239  public void subGen(String s) {240   String x = "", y = "";241   for (int i = 1; i < (1 << s.length()) - 1; i++) {242    for (int j = 0; j < s.length(); j++) {243     if (((1 << j) & i) != 0) {244      x += s.charAt(j);245     }246    }247 248    for (int j = 0; j < s.length(); j++) {249     if (((1 << j) & (~i)) != 0) {250 251      y += s.charAt(j);252 253     }254    }255    if (count_sup(x + y) / count_sup(x) >= minconf) {256     ruleMap.put(x, y);257    }258    x = "";259    y = "";260 261   }262  }263 264  public void ruleGen() {265   String s;266   Iterator iterator = maxFrequency.iterator();267   while (iterator.hasNext()) {268    s = (String) iterator.next();269    subGen(s);270   }271  }272 273  // for test274  public void print1() {275   Iterator temp = candidateSet[0].iterator();276   while (temp.hasNext())277    System.out.println(temp.next());278  }279 280  // for test281  public void print2() {282   Iterator temp = frequencySet[0].iterator();283   while (temp.hasNext())284    System.out.println((String) temp.next());285  }286 287  // for test288  public void print3() {289   canditate_gen(1);290   frequent_gen(2);291   Iterator temp = candidateSet[1].iterator();292   Iterator temp1 = frequencySet[1].iterator();293   while (temp.hasNext())294    System.out.println("候选" + (String) temp.next());295   while (temp1.hasNext())296    System.out.println("频繁" + (String) temp1.next());297  }298 299  public void print_canditate() {300 301   for (int i = 0; i < frequencySet[0].size(); i++) {302    Iterator ix = candidateSet[i].iterator();303    Iterator iy = frequencySet[i].iterator();304    System.out.print("候选集" + (i + 1) + ":");305    while (ix.hasNext()) {306     System.out.print((String) ix.next() + "\t");307     //System.out.print(toDigit((String) ix.next()) + "\t");308    }309    System.out.print("\n" + "频繁集" + (i + 1) + ":");310    while (iy.hasNext()) {311     System.out.print((String) iy.next() + "\t");312     //System.out.print(toDigit((String) iy.next()) + "\t");313    }314    System.out.println();315   }316  }317 318  319  private String toDigit(String str) {320   if (str != null) {321    StringBuffer temp = new StringBuffer();322 323    for (int i = 0; i < str.length(); i++) {324     char c = str.charAt(i);325     temp.append(((int) c - 65) + " ");326    }327 328    return temp.toString();329   } else {330    return null;331   }332 333  }334 335  public String[] getTrans_set() {336   return transSet;337  }338 339  public void setTrans_set(String[] transSet) {340   transSet = transSet;341  }342 343  public double getMinsup() {344   return minsup;345  }346 347  public void setMinsup(double minsup) {348   this.minsup = minsup;349  }350 351  public double getMinconf() {352   return minconf;353  }354 355  public void setMinconf(double minconf) {356   this.minconf = minconf;357  }358 359  public void run() {360   int k = 1;361 362   item1_gen();363 364   do {365    k++;366    canditate_gen(k);367    frequent_gen(k);368   } while (!is_frequent_empty(k));369   frequencyIndex = k - 1;370   print_canditate();371   maxfrequent_gen();372   print_maxfrequent();373   ruleGen();374   rulePrint();375 376  }377  378  public static void main(String[] args) {379   Apriori ap = new Apriori();380   ap.run();381  }382  383  384  385  386 387 }

 

数据挖掘算法 Apriori 例子+源码