请教由频繁项集生成关联规则的c/c++实现

dainuo1990 2015-02-02 11:20:44
现在我可以实现找到频繁N项集,但是怎么生成关联规则呢?

我现在的思路是,例如频繁3项集{1,2,5}:

1、找到{1,2,5}的非空子集{1}、{2}、{5}、{1,2}、{2,5}、{1,5}。

2、将这些子集在频繁1项集、频繁2项集中定位,读出他们的支持度。

3、再分别进行两两组合(排除有包含关系的组合,例如{1}和{1,2}),算置信度,并按最小置信度进行筛选。

在实现的过程中,我是先进行步骤1,比如找到了{1},然后就去频繁1项集中找{1}的支持度;然后再找{1}的补集{2,5},再去频繁2项集中找{2,5}的支持度…………现在我还没实现,就发现用了6、7层循环了,都有点绕蒙了!

现在觉得应该是我的方法思路不对,所以请各位大神指点!

请教步骤1应该怎么实现?或者更详细的流程介绍?或者现成的代码?

万分感谢!!!!!

下面是生成频繁项集的算法:


#include"stdafx.h"
#include<stdio.h>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<iomanip>
#include<string>
#include<vector>
#include<time.h>

using namespace std;


typedef struct
{
int item[100]; //数据项
} D_Node; //数据库D

typedef struct
{
int item[100]; //数据项,用item[0]保存支持度
} C_Node; //候选集

typedef struct
{
int item[100]; //数据项,用item[0]保存支持度
} L_Node;//频繁集

C_Node C[100][100];
L_Node L[100][100];
D_Node D[100];
int min_supp; //最小支持度

void InPut()
{
int n=0,i,size=1000;
char sLine[1000]={0};
min_supp=2;

fstream infile("input.txt");
while(infile.getline(sLine,size))
{
n++;
D[n].item[0]=atoi(strtok(sLine,",\n"));
for(i=1;i<=D[n].item[0];i++)
{
D[n].item[i]=atoi(strtok(NULL,",\n"));
}
}
D[0].item[0]=n;
infile.close();
return;

}//end of InPut

void C1()
{
//功能:扫描数据集D生成1项候选集C1
//输入:数据集D
//输出1项候选集C1
//初始条件 数据集D 非空
int i,j,k;
int no=1,temp=0;
C[1][0].item[0]=0; //1 项集的个数,在本算法中,用C[n][k].item[0]来保存候选集Cn的第k项的支持度
if(D[0].item[0]!=0) //数据库D的项的个数不等于0
{
C[1][1].item[1]=D[1].item[1]; //数据库D的第一项内容给了候选集C1的第一项

}

for(i=1;i<=D[0].item[0];i++) //for1 D[0].item[0]是数据库D的项的个数
{

for(j=1;j<=D[i].item[0];j++) //for2 D[i].item[0]是数据库D的第i项中元素的个数
{
temp=1;
for(k=1;k<=no;k++) //for3 在已有的项集加上支持度if1或者产生新的项集if2
{
if(C[1][k].item[1]==D[i].item[j])
{
C[1][k].item[0]++; //支持度加1
temp=0; //

} //if1
}//end for3


if(temp)//生成新的项集
{
C[1][++no].item[1]=D[i].item[j];
C[1][no].item[0]=1;
} //if2

}//end for2

} // end for1
C[1][0].item[0]=no; //C(1)项集的个数
} //end of C1()

void Cn( int n)
{
//用频繁集Ln-1为基础,通过连接得到n项候选集Cn

int i,j,k,p,q,s,t,num,a;
int no=0,temp=0,count;
C[n][0].item[0]=0; //初始化
//printf("in Cn(%d) n=%d/n",n,n);
//printf("in Cn(%d) C[%d][0].item[0]=%d/n",n,n,C[n][0].item[0]);
num=L[n-1][0].item[0]; //num是Ln-1项集的数据个数

for(i=1;i<=num;i++) //for1
{
for(j=i+1;j<=num;j++) //for2
{
temp=1; //测试是否满足联结条件

if(n>2)//if 1
{
for(k=1;k<n-1;k++) //for3
{
if(L[n-1][i].item[k]!=L[n-1][j].item[k]) //if 2 只有n项之前的都相同,第n项不同时才连接枝
{
temp=0;
break;
}//end if 2
if(k==n-2) //剪枝
{
for(a=1;a<=L[2][0].item[0];a++) //for剪枝 满足if2条件后,测试两个频繁项集的第n项组成的2项集是否在L2中,在的话继续连接,不在的话就说明肯定不是频繁项集,被剪掉
{
if((L[2][a].item[1]==L[n-1][i].item[k+1]&&L[2][a].item[2]==L[n-1][j].item[k+1])||(L[2][a].item[1]==L[n-1][j].item[k+1]&&L[2][a].item[2]==L[n-1][i].item[k+1]))
{
temp=1;
break;
}
else temp=0;
}//end for剪枝

}//end if剪枝
}//end for3
}//end if1
if(temp==1)//满足联结条件 //if 3
{
// printf("in if 2 no=%d/n",no);
no++;
for(p=1;p<=n-1;p++) //for4
{
C[n][no].item[p]=L[n-1][i].item[p];
C[n][no].item[p+1]=L[n-1][j].item[p];
C[n][no].item[0]=0;
}//end for4

for(q=1;q<=D[0].item[0];q++) //for5 测试其支持度
{

count=0; //count用来记数,当所测试的项存在时,count加1,当count=n时,则子集存在

for(s=1;C[n][no].item[s]!=0;s++) //for6
{
for(t=1;t<=D[q].item[0];t++) //for7
{
if(C[n][no].item[s]==D[q].item[t]) //if 4
{ count+=1;
break; //跳出了for7循环
} //end if4
}//end for7

}//end for 6
if(count==n) //if 5
{
C[n][no].item[0]+=1;//子集存在,第no项的支持度加1
} //end if5

}//end for5

C[n][0].item[0]+=1;
}//end if3

}//end for2
}//end for1


}//end of Cn()



void L1()
{
int i,j,k;
j=0;
L[1][0].item[0]=0;

//printf("C[1][0].item[0]=%d/n",C[1][0].item[0]);
for(i=1;i<=C[1][0].item[0];i++) // for1
{
if(C[1][i].item[0]>=min_supp)
{
j+=1;
for(k=1;k<=1;k++) // for2
{
L[1][j].item[k]=C[1][i].item[k];
L[1][j].item[0]=C[1][i].item[0];
// printf("L[1][%d].item[1]=%d ",j,L[1][j].item[1]); 测试功能时加的
// printf(" -------------%d/n",L[1][j].item[0]);

}//end for2
}//end if

}//end for1
L[1][0].item[0]=j;
}//end of L1()


void Ln(int n)
{
int i,j,k;
Cn(n);
j=0;
L[n][0].item[0]=0;
// printf("in Ln(%d) C[%d][0].item[0]=%d/n",n,n,C[n][0].item[0]);
for(i=1;i<=C[n][0].item[0];i++) //for 1
{
if(C[n][i].item[0]>=min_supp)
{
j+=1;
for(k=1;k<=n;k++) //for 2
{
L[n][j].item[k]=C[n][i].item[k];
L[n][j].item[0]=C[n][i].item[0];
} //end for2
} //end if

}//end for1

L[n][0].item[0]=j; //保存数据的个数
}//end of Ln(int n)




void main()
{
fstream outfile("output.txt",ios::out);
clock_t start_time=clock();
{ //被计时测试代码
int i,p,j,k;
int n=1;
InPut();
C1();//初始化,生成1项候选集C1
L1();//得到1项频繁集L1
while(L[n][0].item[0]!=0)
{
n+=1;
Ln(n);
}

for(i=1;i<=n;i++)
{
outfile<<"频繁项目集L"<<i<<"如下:"<<endl;
k=L[i][0].item[0];
if(k!=0)
{
for(p=1;p<=k;p++)
{
outfile<<"{ ";
for(j=1;j<=i;j++)
outfile<<"I"<<L[i][p].item[j]<<" ";
outfile<<"} 支持度:"<<L[i][p].item[0]<<endl;
}//end for
}
else outfile<<"项目集为空"<<endl;
}

}//被测试代码
clock_t end_time=clock();
outfile<< "Running time is: "<<static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000<<"ms"<<endl;//输出运行时间
//return 0;
outfile.close();
}


...全文
781 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_19815803 2015-10-02
  • 打赏
  • 举报
回复
LZ问题解决了没啊,我也是得到频繁项集就不知道怎么办了

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧