码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2014-12-23 21:09:23      阅读:703      评论:0      收藏:0      [点我收藏+]

标签:

 

转自这里

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()) + "\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" : "") + "-->" + y
211      + "\t" + temp);
212    sb.append("  " + x + (x.length() < 5 ? "\t" : "") + "-->" + y
213      + "\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 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() + "\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 例子+源码

标签:

原文地址:http://www.cnblogs.com/fillim/p/4181110.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!