算法:Apriori 输入:D -事务数据库;min_sup -最小支持度计数阈值 输出:L - D中的频繁项集 方法: L1=find_frequent_1-itemsets(D); //找出所有频繁1项集 For(k=2;Lk-1!=null;k++){ Ck=apriori_gen(Lk-1); //产生候选,并剪枝 For each事务t in D{ //扫描D进行候选计数 Ct =subset(Ck,t); //得到t的子集 For each候选c属于Ct c.count++; } Lk={c属于Ck | c.count>=min_sup} } Return L=所有的频繁集; Procedure apriori_gen(Lk-1:frequent(k-1)-itemsets) For each项集l1属于Lk-1 For each项集l2属于Lk-1 If((l1[1]=l2[1])&&( l1[2]=l2[2])&&…….. && (l1[k-2]=l2[k-2])&&(l1[k-1]<l2[k-1])) then{ c=l1连接l2 //连接步:产生候选 if has_infrequent_subset(c,Lk-1) then delete c; //剪枝步:删除非频繁候选 else add c to Ck;} Return Ck; Procedure has_infrequent_sub(c:candidate k-itemset; Lk-1:frequent(k-1)-itemsets) For each(k-1)-subset s of c If s不属于Lk-1 then Return true; Return false; |
/*construct C3...................................................*/ vector<Node3> c3; vector<Node3> l3; vector<Node2>::iterator ite31=l2.begin();//iter 31,32 for(;ite31!=l2.end();ite31++) { vector<Node2>::iterator ite32=l2.begin(); for(;ite32!=l2.end();ite32++) { if(ite31->index_j == ite32->index_i) //step1:找到两个k-1频繁集的项集,它们只有一项不同,且连接后等于X { vector<Node2>::iterator ite33=l2.begin(); for(;ite33!=l2.end();ite33++) { /*step2:如果k-候选集中的项集Y,包含有某个k-1阶子集不属于k-1频繁集,那么Y就不可能是频繁集,应该从候选集中裁剪掉*/ if(ite33->index_i == ite31->index_i && ite33->index_j ==ite32->index_j) { Node3 n3(ite31->index_i,ite31->index_j,ite32->index_j,0); c3.push_back(n3); } } } } }
如下是A Priori算法的实现。计算到了L3。
<pre name="code" class="cpp"><pre name="code" class="cpp">/* 这个程序是数据挖掘中的Apriori算法 Apriori算法的描述 Apriori算法的第一步是简单统计所有含一个元素的项集出现的频率,来决定最大的一维项目集. 在第k步,分两个阶段,首先用一函数sc_candidate(候选),通过第(k-1)步中生成的最大项目集Lk-1来生成侯选项目集Ck. 然后搜索数据库计算侯选项目集Ck的支持度. 为了更快速地计算Ck中项目的支持度, 文中使用函数count_support计算支持度. Apriori算法描述如下 (1) C1={candidate1-itemsets}; (2) L1={c∈C1|c.count≥minsupport}; (3) For(k=2,Lk-1≠Φ,k++) //直到不能再生成最大项目集为止 (4) Ck=sc_candidate(Lk-1); //生成含k个元素的侯选项目集 (5) for all transactions t∈D //办理处理 (6) Ct=count_support(Ck,t); //包含在事务t中的侯选项目集 (7) for all candidates c∈Ct (8) c.count=c.count+1; (9) next (10) Lk={c∈Ck|c.count≥minsupport}; (11) next (12) resultset=resultset∪Lk*/ #include <stdio.h> #include<string.h> #include <iostream> #include <vector> #include <algorithm> #define D 9 /*D数事务的个数*/ #define MinSupCount 2 /*最小事务支持度数*/ #define ItemN 5 using namespace std; int hash1(char c) { return (int)c-(int)'a'; } class Node1 { public: int index_i; int count; Node1() { index_i=-1; count=0; } Node1(int i, int c):index_i(i),count(c) { } }; class Node2 { public: int index_i; int index_j; int count; Node2() { index_i=-1; index_j=-1; count = 0; } Node2(int i, int j, int c):index_i(i),index_j(j),count(c) { } }; class Node3 { public: int index_i; int index_j; int index_k; int count; Node3() { index_i=-1; index_j=-1; index_k=-1; count =0; } Node3(int i, int j, int k, int c):index_i(i),index_j(j),index_k(k), count(c) { } }; void printNode3(vector<Node3>& n3) { vector<Node3>::iterator ite = n3.begin(); for(;ite!=n3.end();ite++) { cout<<(char)(ite->index_i+'a')<<(char)(ite->index_j+'a')<<(char)(ite->index_k+'a')<<":"<<ite->count<<"\t"; } cout<<endl; } void printNode2(vector<Node2>& n2) { vector<Node2>::iterator ite = n2.begin(); for(;ite!=n2.end();ite++) { cout<<(char)(ite->index_i+'a')<<(char)(ite->index_j+'a')<<":"<<ite->count<<"\t"; } cout<<endl; } void printNode1(vector<Node1>& n1) { vector<Node1>::iterator ite = n1.begin(); for(;ite!=n1.end();ite++) { cout<<(char)(ite->index_i+'a')<<":"<<ite->count<<"\t"; } cout<<endl; } void main() { /*这里的a,b,c,d,e 分别代表着书上数据挖掘那章的I1,I2,I3,I4,I5 */ char a[10][10]={ {'a','b','e'}, {'b','d'}, {'b','c'}, {'a','b','d'}, {'a','c'}, {'b','c'}, {'a','c'}, {'a','b','c','e'}, {'a','b','c'} }; //total is D /*c1, hash the first time to b*/ //at first. hash the value vector<Node1> l1; int b[10]={0}; int ItemNumber=0; for(int i=0;i<D;i++) { for(int j=0;a[i][j]!='\0';j++) { int item = hash1(a[i][j]); if(b[item]==0) { b[item]++; ItemNumber++; } else { b[item]++; } } } /*L1........................................................*/ for(int i=0;i<ItemNumber;i++) { if(b[i]>=MinSupCount) { Node1 n1(i,b[i]); l1.push_back(n1); } } cout<<"print L1................................................"<<endl; printNode1(l1); /*construct c2...........................................................*/ vector<Node2> c2; vector<Node2>l2; vector<Node1>::iterator ite21=l1.begin(); //ite21,22 for(;ite21!=l1.end();ite21++) { vector<Node1>::iterator ite22=l1.begin(); for(;ite22!=l1.end();ite22++) { if(ite22->index_i > ite21->index_i) { Node2 n2(ite21->index_i,ite22->index_i,0); c2.push_back(n2); } } } /*count C2.........................................................................*/ for(int k=0;k<D;k++) { for(int i=0;a[k][i]!='\0';i++) { int h1 = hash1(a[k][i]); for(int j=i+1;a[k][j]!='\0';j++) { int h2=hash1(a[k][j]); vector<Node2>::iterator ite=c2.begin(); for(;ite!=c2.end();ite++) { if(ite->index_i ==h1 && ite->index_j == h2) ite->count++; } } } } /*prune C2 to L2.......................................................*/ l2.clear(); vector<Node2>::iterator ite2=c2.begin(); //ite2 for(;ite2!=c2.end();ite2++) { if(ite2->count>=MinSupCount) { l2.push_back(*ite2); } } cout<<"print L2............................................"<<endl; printNode2(l2); /*construct C3...................................................*/ vector<Node3> c3; vector<Node3> l3; vector<Node2>::iterator ite31=l2.begin();//iter 31,32 for(;ite31!=l2.end();ite31++) { vector<Node2>::iterator ite32=l2.begin(); for(;ite32!=l2.end();ite32++) { if(ite31->index_j == ite32->index_i) { Node3 n3(ite31->index_i,ite31->index_j,ite32->index_j,0); c3.push_back(n3); } } } /*countC3.................................................*/ for(int out=0;out<D;out++) { for(int i=0;a[out][i]!='\0';i++) { int h1 = hash1(a[out][i]); for(int j=i+1;a[out][j]!='\0';j++) { int h2=hash1(a[out][j]); for(int k=j+1;a[out][k]!='\0';k++) { int h3=hash1(a[out][k]); vector<Node3>::iterator ite=c3.begin(); for(;ite!=c3.end();ite++) { if(ite->index_i ==h1 && ite->index_j == h2 && ite->index_k==h3) ite->count++; } } } } } /*prune C3 to l3....................................*/ l3.clear(); vector<Node3>::iterator ite3=c3.begin(); //ite3 for(;ite3!=c3.end();ite3++) { if(ite3->count>=MinSupCount) { l3.push_back(*ite3); } } cout<<"print L3..........................."<<endl; printNode3(l3); system("pause"); }