Apriori算法实验报告文档格式.docx

上传人:b****3 文档编号:16790211 上传时间:2022-11-26 格式:DOCX 页数:18 大小:101.17KB
下载 相关 举报
Apriori算法实验报告文档格式.docx_第1页
第1页 / 共18页
Apriori算法实验报告文档格式.docx_第2页
第2页 / 共18页
Apriori算法实验报告文档格式.docx_第3页
第3页 / 共18页
Apriori算法实验报告文档格式.docx_第4页
第4页 / 共18页
Apriori算法实验报告文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Apriori算法实验报告文档格式.docx

《Apriori算法实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《Apriori算法实验报告文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

Apriori算法实验报告文档格式.docx

string>

>

datavec;

//原始数据项集

candidatevec;

//候选项集

frequentvec;

//频繁项集

ofstreamoutFile;

intround=1;

//生成项集轮次

longtrancount=0;

//原始事务总数

//判断某个工程在某一个事务中是否存在,存在那么值为1,反之为0

string,bool>

>

bitmap;

Apriori算法的第一步是简单统计所有含一个元素的项集出现的频率,来决定频繁1项集。

在第k步,分两个阶段:

1,用函数genCanItemsetK,通过第(k-1)步中生成的频繁(k-1)项集来生成侯选k项集;

2.计算侯选k项集的支持度,并找出频繁k项集。

Apriori算法描述如下

getOriData();

//获取原始数据集,并统计事务个数

genCanItemset1();

//产生输出候选1项集

genFreItemset1();

//产生频繁项集

if(!

frequentvec.empty())//根据频繁1项集,执行程序

{

do

{

genCanItemsetK();

//生成并输出候选k项集

genFreItemsetK();

//计算并输出频繁k项集

}while(!

frequentvec.empty());

//频繁项集不为空,那么循环继续

}

其中,产生候选k项集函数genCanItemsetK中涉及两个重要函数,项集合并函数mergeItem和剪枝函数cutNotCanItemsetK。

3、函数方法说明

//获取原始数据集,并统计事务个数

voidgetOriData();

//合并生成新的候选项集

mergeItem(vector<

vect1,vector<

vect2,intround);

//判断项集item是否已经存在候选项集集合items中,存在那么返回1

intisExist(vector<

item,vector<

items);

//产生并输出候选1项集

voidgenCanItemset1();

//产生并输出频繁1项集

voidgenFreItemset1();

//产生并输出候选k-项集〔k>

=2〕

voidgenCanItemsetK();

//产生并输出频繁k-项集〔k>

voidgenFreItemsetK();

//剪枝:

剪去合并后项集中含有非频繁项集中的项

voidcutNotCanItemsetK(vector<

&

item);

五、实验截图

1.程序运行界面

2.输出文件截图1

3.输出文件截图1

六、实验总结

做完这个实验,有如下收获:

1.同一数据集,最小支持度越小,那么产生的频繁项集维数越高,程序运行时间越长;

2.更加深刻理解了:

频繁子集的任何子集一定是频繁的,子集频繁父亲一定频繁;

3.Apriori也存在缺点:

第一在每一步产生侯选工程集时循环产生的组合过多,没有排除不应该参与组合的元素;

第二,每次计算项集的支持度时,开销会随着数据的增多而成几何级增长。

七、附

1.程序源码main.cpp

#include<

iostream>

fstream>

vector>

map>

algorithm>

iomanip>

usingnamespacestd;

intmain()

{

getOriData();

cout<

<

"

请输入结果文件名:

"

;

//pause

stringfName;

cin>

fName;

请输入最小支持度:

minsup;

outFile.open(fName,ios:

:

trunc);

outFile<

最小支持度为minsup="

<

minsup<

endl;

genCanItemset1();

genFreItemset1();

frequentvec.empty())//判断频繁1项集是否为空,为空那么退出

outFile.close();

\n结果已保存到"

fName<

文件!

\n"

system("

pause"

);

return0;

}

voidgetOriData()

intflag;

数据集文件:

\n1.dataA.txt\n2.dataB.txt\n请输入〔1选择dataA,其他选择2〕\n"

flag;

stringfilename;

if(flag==1)

filename="

dataA.txt"

//翻开数据文件

else

dataB.txt"

ifstreamfile(filename);

file)//检查文件是否翻开成功

{

cout<

Failtoopendatafile!

endl;

system("

exit(0);

stringtemp;

vector<

item;

//项集的临时vector

原始数据集:

intbegin,end;

while(getline(file,temp))//一行一行读入数据

trancount++;

begin=0;

temp.erase(0,temp.find_first_not_of("

\r\t\n"

));

//去除字符串首部的空格

temp.erase(temp.find_last_not_of("

\r\t\n"

)+1);

//去除字符串尾部的空格

while((end=temp.find('

'

begin))!

=string:

npos)//每一个事务中的项是以空格为分隔符的

{

item.push_back(temp.substr(begin,end-begin));

//将每一个项插入item中

begin=end+1;

}

item.push_back(temp.substr(begin));

//一个事务中的最后一项

datavec.push_back(item);

//将一个事务中的所有项当成一个整体插入另一个大的vector中

item.clear();

//清空item

cout<

temp<

}

file.close();

voidgenCanItemset1()

map<

item_map;

for(intix=0;

ix!

=datavec.size();

++ix)

for(intiy=0;

iy!

=datavec[ix].size();

++iy)

items_count[datavec[ix].at(iy)]++;

//该项集的计数加1

item_map[datavec[ix].at(iy)]=true;

//表示该工程在该事务中存在,值为1,否那么默认为0

bitmap.push_back(item_map);

item_map.clear();

//这里一定要清空一下

const_iteratormap_it=items_count.begin();

候选1项集:

while(map_it!

=items_count.end())//输出候选1项集

outFile<

{"

map_it->

first<

}"

map_it++;

voidgenFreItemset1()

outFile<

频繁1项集:

vector<

//项集的临时vector

=items_count.end())//频繁1项集

if(((float)map_it->

second/(float)trancount)>

minsup||fabs(((float)map_it->

second/(float)trancount)-minsup)<

1.0e-7)//支持度大于0.2

outFile.setf(ios:

fixed);

outFile<

支持度:

setprecision

(2)<

(float)map_it->

second/(float)trancount<

item.push_back(map_it->

first);

frequentvec.push_back(item);

//插入频繁1项集的vector中

voidgenCanItemsetK()

//生成下一轮的候选项集

intst=frequentvec.size();

candidatevec.clear();

//去除上一轮的候选项集

for(intst1=0;

st1<

st;

st1++)

for(intst2=st1+1;

st2<

st2++)

item=mergeItem(frequentvec[st1],frequentvec[st2],round);

//调用函数合并生成下一轮的候选项集

if(!

item.empty()&

&

!

isExist(item,candidatevec))//假设经过判断处理后返回的vector不为空且还不存在该项集,那么作为候选项集参加候选vector中

cutNotCanItemsetK(item);

round++;

候选"

round<

项集:

=candidatevec.size();

++ix)//输出候选项集

outFile<

=candidatevec[ix].size();

outFile<

candidatevec[ix].at(iy);

if(candidatevec.empty())//候选项集为空

项集为空!

//产生并输出频繁k-项集(k>

=2)

voidgenFreItemsetK()

//标记某个项集在某条事务中是否出现,出现为1,不出现为0,如:

{I1I2}

intcount;

//统计某个想集在整个交易的事务集中出现的次数

stringtempstr;

//临时string,用于串接各个项成一个字符串:

如:

I1I2I3串接为"

I1I2I3"

intmark;

//为防止执行多余的字符串串接工作

frequentvec.clear();

//去除上一轮的频繁项集

for(intsx=0;

sx!

++sx)//构造下一轮的频繁项集

mark=1;

count=0;

for(intsy=0;

sy!

=bitmap.size();

++sy)

flag=1;

//初始化为1,表出现

for(intsz=0;

sz!

=candidatevec[sx].size();

++sz)

if(bitmap[sy][candidatevec[sx].at(sz)]==false)//存在某一个子项不存在,那么没出现项集

{

flag=0;

}

if(mark==1)//只串接一次,如I1I2否那么为10个I1I2的串接

tempstr+=candidatevec[sx].at(sz);

//串接字符串

if(flag)//flag仍然为1,表示该项集在该条事务中出现了,计数加1

count++;

mark++;

if(((float)count/(float)trancount)>

minsup||fabs(((float)count/(float)trancount)-minsup)<

frequentvec.push_back(candidatevec[sx]);

//插入频繁项集

items_count[tempstr]=count;

//对应该项集的计数值

/////////假设此时生成的tempstr为I1I2I3,为便于后面的求置信度的计算,这里需要产生I2I1I3,I1I3I2等组合,并

//在items_count中给它们赋予和I1I2I3相同的值

sort(candidatevec[sx].begin(),candidatevec[sx].end());

//排序

stringtempstr2;

while(next_permutation(candidatevec[sx].begin(),candidatevec[sx].end()))//取下一排列组合

for(inttempst=0;

tempst!

tempst++)//拼接出该字符串组合

tempstr2+=candidatevec[sx][tempst];

items_count[tempstr2]=count;

tempstr2.erase();

}

tempstr.erase();

frequentvec.empty())//频繁项集不为空

频繁"

for(intsx=0;

=frequentvec.size();

++sx)//输出频繁项集

=frequentvec[sx].size();

outFile<

frequentvec[sx].at(sz);

tempstr+=frequentvec[sx].at(sz);

(float)items_count[tempstr]/(float)trancount<

tempstr.erase();

没有"

-频繁项集,Apriori算法结束!

//两个项集合并(要求只有一项不同)成一个新的项集〔做为候选集〕

vect2,intround)

intcount=0;

//统计两个vector中相同的项的数目

vect;

tempMap;

//辅助判断两个vector中重复的项

for(unsignedintst=0;

st<

vect1.size();

st++)

tempMap[vect1[st]]++;

vect.push_back(vect1[st]);

vect2.size();

tempMap[vect2[st]]++;

if(tempMap[vect2[st]]==2)//表示这两项相同

count++;

else

vect.push_back(vect2[st]);

if((count+1)!

=round)//要求两个工程集只有一个工程不相同,其他都相同,如:

I1I2I4和I1I2I3

vect.clear();

returnvect;

item)

////////实现剪枝//////////////////////////

tempvec;

boolfound=false;

//是否包含有非频繁的子集,为1表示含有,有的话进行剪枝,如假设I1I4为非频繁项集,那么I1I2I4要剪枝掉

stringteststr;

inttestint;

tempvec=item;

sort(tempvec.begin(),tempvec.end());

while(next_permutation(tempvec.begin(),tempvec.end()))//遍历所有的组合I1I2I4,要变成I1I4I2或其他如I2I1I4才能判断它包含I1I4这个非频繁项集

for(inttempst=0;

=tempvec.size();

tempstr+=tempvec[tempst];

for(map<

const_iteratortempit=items_count.begin

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1