标签:
转自这里
Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。其核心是基于
两阶段频集思想的递推算法。该关联规则在分类上属于单维、单层、布尔关联规
则。在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集。
由Agrawal等人提出的Apriori是经典的关联规则和频繁项集挖掘算法,围绕着它的改进和实现有大量的文献。该算法是挖掘产生布尔关联规则频繁项目集的经典算法,从其产生到现在对关联规则挖掘方面的研究有着很大的影响。
为了提高频繁项目的挖掘效率,Apriori算法利用了两个重要的性质,用于压缩搜索的空间。
【1】若X为频繁项目集,则X的所有子集都是频繁项目集。
【2】若X为非频繁项目集,则X的所有超集均为非频繁项目集。
Apriori算法的处理流程为:宽度优先搜索整个项集空间,从k=0开始,迭代产生长度为k+1的候选项集的集合Ck+1。候选项集是其所有子集都是频繁项集的项集。C1由I0中所有的项构成,在第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 }
标签:
原文地址:http://www.cnblogs.com/fillim/p/4181110.html