zoukankan      html  css  js  c++  java
  • 数据挖掘算法 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等于空集时结束。

    算法  Apriori
    
    Input:          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) end
    
    Procedure 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) end
    
    Procedure 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                   }   //if
    100 
    101                }//end for3
    102            
    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 for2
    111   
    112     } // end  for1
    113 
    114     C[1][0].item[0]=no;//数据项的个数 
    115 
    116 }  //end of  C1()
    117 
    118 
    119 void Cn( int n)
    120 { 
    121  //用频繁集Ln-1为基础,通过连接得到n项候选集Cn
    122  
    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++)   //for2
    136          {
    137   
    138       temp=1;  //测试是否满足联结条件
    139               if(n>2)//if 1
    140               {
    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 1
    146 
    147                     }//end for3
    148 
    149                  }//end if1
    150 
    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++)  //for6
    167                           {
    168                                       for(t=1;t<=D[q].item[0];t++)  //for7
    169            {
    170                                              if(C[n][no].item[s]==D[q].item[t])
    171 
    172             {   count+=1;
    173                       break;
    174             }
    175            }//end for7
    176                                     
    177           }//end for 6
    178                            if(count==n) C[n][no].item[0]+=1;//子集存在,第no项的支持度加1
    179                   
    180        }//end for5
    181                           
    182                           
    183                       C[n][0].item[0]+=1;
    184        }//end if2
    185            }//end for2
    186 
    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 for1
    219    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 1
    232    {
    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 if
    240 
    241 
    242    }//end for1
    243 
    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              }//for
    271            
    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项候选集C1
    285  L1();//得到1项频繁集L1
    286     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.cpp
    306 
    307 //////////////////////////////////////////////////////////////////////////
    308 /*
    309 *
    310 *
    311 *
    312 * 文件名称:FAST apriori.cpp
    313 
    314 *
    315 * 摘 要:采用位运算提高算法的效率
    316 
    317 *
    318 * 当前版本:1.0
    319 
    320 * 完成日期:2006.06.20
    321 *
    322 */////////////////////////////////////////////////////////////////////////
    323 
    324 #include <stdio.h>
    325 #include <string.h>
    326 
    327 typedef  struct
    328 {
    329 char item[10];  //数据项
    330 int min_supp_count;//最小支持度数
    331 } C_Node;      //候选集
    332 
    333 
    334 typedef  struct
    335 {
    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 InPut
    360 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;//子集存在,支持度数加1
    403     }
    404    }
    405   }
    406 
    407 }
    408 
    409 void  C1()
    410 {
    411  //功能:扫描数据集D生成1项候选集C1
    412  //输入:数据集D
    413  //输出1项候选集C1
    414  //初始条件 数据集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项候选集Cn
    432  
    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++)   //for2
    444          {
    445   
    446       temp=1;  //测试是否满足联结条件
    447               if(n>2)//if 1
    448               {
    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 1
    454 
    455                     }//end for3
    456 
    457                  }//end if1
    458 
    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 if2
    470            }//end for2
    471 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;//频繁集的个数,初始为0
    481    
    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 for1
    491    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              }//for
    506            
    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 1
    521    {
    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 if
    529 
    530 
    531    }//end for1
    532 
    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              }//for
    549            
    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项候选集C1
    564  L1();//得到1项频繁集L1
    565   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   else
    144    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()) + "	");
    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 ? "	" : "") + "-->" + y
    211      + "	" + temp);
    212    sb.append("  " + x + (x.length() < 5 ? "	" : "") + "-->" + y
    213      + "	" + temp + "	
    ");
    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 test
    274  public void print1() {
    275   Iterator temp = candidateSet[0].iterator();
    276   while (temp.hasNext())
    277    System.out.println(temp.next());
    278  }
    279 
    280  // for test
    281  public void print2() {
    282   Iterator temp = frequencySet[0].iterator();
    283   while (temp.hasNext())
    284    System.out.println((String) temp.next());
    285  }
    286 
    287  // for test
    288  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() + "	");
    307     //System.out.print(toDigit((String) ix.next()) + "	");
    308    }
    309    System.out.print("
    " + "频繁集" + (i + 1) + ":");
    310    while (iy.hasNext()) {
    311     System.out.print((String) iy.next() + "	");
    312     //System.out.print(toDigit((String) iy.next()) + "	");
    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 }
  • 相关阅读:
    多线程02
    多线程01
    CSS
    Mybatis CRUD中万能Map的用法及优势
    Tomcat配置
    Node.js+Vue+Webpack
    Java的几种常见排序算法
    maven插件 mybatis逆向工程
    ssm依赖
    mybatis spring整合依赖配置
  • 原文地址:https://www.cnblogs.com/fillim/p/4181110.html
Copyright © 2011-2022 走看看