最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

数据挖掘实验三应用 Apriori 算法挖掘频繁项集

来源:动视网 责编:小OO 时间:2025-09-28 19:31:05
文档

数据挖掘实验三应用 Apriori 算法挖掘频繁项集

实验三、应用Apriori算法挖掘频繁项集学院计算机科学与软件学院•实验目的:(1)熟悉VC++编程工具和Apriori频繁项集挖掘算法。(2)根据管理层的需求,确定数据挖掘的任务,明确数据挖掘的功能,也就是明确要挖掘什么。(3)由确定的数据挖掘任务,从实验一处理后的结果中,采用切块或切片等联机分析处理技术,选择出挖掘任务相关数据。(4)用VC++编程工具编写Apriori算法的程序,对任务相关数据运行Apriori算法,挖掘出所有的频繁项集。1.写出实验报告。•实验原理:1、Apriori算
推荐度:
导读实验三、应用Apriori算法挖掘频繁项集学院计算机科学与软件学院•实验目的:(1)熟悉VC++编程工具和Apriori频繁项集挖掘算法。(2)根据管理层的需求,确定数据挖掘的任务,明确数据挖掘的功能,也就是明确要挖掘什么。(3)由确定的数据挖掘任务,从实验一处理后的结果中,采用切块或切片等联机分析处理技术,选择出挖掘任务相关数据。(4)用VC++编程工具编写Apriori算法的程序,对任务相关数据运行Apriori算法,挖掘出所有的频繁项集。1.写出实验报告。•实验原理:1、Apriori算
实验三、应用 Apriori 算法挖掘频繁项集

学院 计算机科学与软件学院

•实验目的:

(1)熟悉 VC++编程工具和 Apriori 频繁项集挖掘算法。

(2)根据管理层的需求,确定数据挖掘的任务,明确数据挖掘的功能,也

就是明确要挖掘什么。

(3)由确定的数据挖掘任务,从实验一处理后的结果中,采用切块或切片

等联机分析处理技术,选择出挖掘任务相关数据。

(4)用 VC++编程工具编写 Apriori 算法的程序,对任务相关数据运行 Apriori

算法,挖掘出所有的频繁项集。

1.写出实验报告。

•实验原理:

1 、Apriori  算法

    Apriori 使用一种称作逐层搜索的迭代方法,k 项集用于探索(k+1)项集。

首先,通过扫描数据库,累计每个项的计数,并收集满足最小支持度的项,

找出频繁 1 项集的集合。该集合记作 L 1 。然后,L 1  用于找频繁 2 项集的集合L 2 ,L 2 用于找 L 3 ,如此下去,直到不能再找到频繁 k 项集。找每个 L k  需要一次数据库全扫描。

2、提高频繁项集逐层产生的效率

    Apriori 性质:频繁项集的所有非空子集也必须是频繁的。 

三、 实验内容:

1、实验内容

    在给定的数据中提取统一购物篮购买的商品信息,由这些数据构成事务数据

库 D,挖掘其中的频繁项集 L。

挖掘频繁项集的算法描述如下:

Apriori 算法:使用逐层迭代找出频繁项集

输入:事务数据库 D;最小支持度阈值。

输出:D 中的频繁项集 L。

(1) L 1 = find_frequent_1-itemsets(D); // 挖掘频繁 1-项集,比较容易

(2) for (k=2;L k-1 ≠Φ ;k++) {

(3) C k  = apriori_gen(L k-1 ,min_sup); // 调用 apriori_gen 方法生成候选频繁

k-项集分为两步:合并、减枝

(4) for each transaction t ∈ D { // 扫描事务数据库 D

(5) Ct = subset(C k ,t);

(6) for each candidate c ∈ Ct

(7) c.count++; // 统计候选频繁 k-项集的计数

(8) }

(9) L k ={c ∈ Ck|c.count≥min_sup} // 满足最小支持度的 k-项集即为频

繁 k-项集

(10) }

(11) return L= ∪  k  L k ; // 合并频繁 k-项集(k>0)

算法在根据频繁 k-1 项集生成频繁 K 项集过程中要计算频繁 K 项集中每个

元素的支持度,并计算 K 项集中每个 k-1 项子集是否在 F k-1 中,上述两条任何一

条不满足,则删去这个 K 项集中的元素。

2 、实验过程

    1、打开试验用数据,读取出同一流水号的商品 ID 并取前 5 位,生成以行为

单位生成事务数据集 transitions;

    2、ind_frequent_1-itemsets 生成频繁一项集

for(each transaction in transitions){

for(each item in transaction){

oneItemSet;

oneItemSet.count++;//对 1 项集进行计数

}

}

    3、apriori-gen (L k-1 ) 候选集产生算法

For all itemset p∈Lk-1 do

For all itemset q∈Lk-1 do

If p.item1=q.item1, p.item2=q.item2, …,p.itemk-2=q.itemk-2,

p.item k-1 !=q.item k-1

then

begin c=p∞q//p、q 合并后任意的 L k-1 子集

if has_infrequent_subset(c, L k-1 )

then delete c //存在 c 不属于 L k-1 剪枝

else add c to Ck

End

Return Ck

    4、has_infrequent_subset(c, L k-1 )判断候选集的元素

For all (k-1)-subsets of c do

If Not(S∈Lk-1) THEN return TRUE;

Return FALSE;

1.流程图

4、主要程序代码

1、//产生事务数据库代码(加注释)

#include

#include

#include

#include

using namespace std;

class Sales_n

{

public:

    string serial;

    int market;

    char date[10];

    int sn;

 int id;

    float num;

    float price;

};

int main()

{  

//////////打开并创建txt文件//////////////////////////////////

    char name1[50],name2[50];

    ifstream infile;

cout<<"选择要打开的文件:1019n.txt 1020n.txt 1021n.txt"< cin>>name1;

    infile.open(name1,ios::in);  

    /*string contents;*/

    if(infile.fail())

    {

     cout << "error open!" << endl;

    }

cout<<"要保存的文件名:"< cin>>name2;

     ofstream outfile(name2,ios::out);

     if(!outfile)

 {

cout<<"open eror!"<     exit(1);

 }

    //////////////////////访问预处理文件/////////////////////////////////////////////

    Sales_n sal[10000];

    int sal_size=0;

    int ser_size=0;

    int m = 0,n = 1;

     int  new1[3400][20]={0};             //暂时储存商品ID

    while(!infile.eof())

    {

infile >> sal[sal_size].serial >> sal[sal_size].market >> sal[sal_size].date>> sal[sal_size].sn>> sal[sal_size].id>> sal[sal_size].num>> sal[sal_size].price;

    sal_size++;

    }

    ///////////////取统一流水的商品ID前三位按升序无重复的保存起来/////////////////////////

    new1[0][0]=sal[0].id/10000;

     for (int i =1;i    {  

        if (sal[i].serial==sal[i-1].serial)

        { 

            new1[m][n]=sal[i].id/10000;            //////流水号相同

            n++;

         //outfile<        }

        else

        {  

            ///////排序//////////

         for(int k = 0;k            {

         for(int j = 0;j < n-k-1;j++)

            {  

if(new1[m][j] > new1[m][j+1])

            {  

                int t = new1[m][j];  

                new1[m][j] = new1[m][j+1];  

                new1[m][j+1] = t;  

            }  

        

            }

            }

         for(int l= 0;l< n;l++)

            {

                if(new1[m][l-1]!=new1[m][l])

     outfile<            }

         outfile<            m++;

            n = 0;

            new1[m][n]=sal[i].id/10000;

            n++;

            

        }

    }  

 infile.close();//关闭文件

 outfile.close();//关闭文件

system( "PAUSE ");

}

2、//Apriori算法挖掘频繁项集support = 2(加注释)

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

const int minsup=2;  //设置最小支持度

map items_count; //统计各个项集的数目

vector mergeItem(vector vect1,vector vect2,int round); //合并生成新的候选项集

int isExist(vector item,vector >items); //判断项集item是否已经存在候选项集集合items中,存在则返回

vector mergeItem(vector vect1,vector vect2,int round) //判断两个项集是否可以合并(要求只有一项不同)成一个新的项集(做为候选集)

{

   ////////////////////////////////////////////剪枝工作////

   int count=0;     //统计两个vector中相同的项的数目

vector vect;

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

for(vector::size_type st=0;st   {

      tempMap[vect1[st]]++;

      vect.push_back(vect1[st]);

   }

for(int st=0;st   {

      tempMap[vect2[st]]++;

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

      {

         count++;

      }

      else

      {

         vect.push_back(vect2[st]);

      }

   }

   if((count+1)!=round)       //要求两个项目集只有一个项目不相同,其他都相同   {

      vect.clear();

   }

   return vect;

}

int isExist(vector item,vector >items) //判断项集item是否已经存在候选项集集合items中,存在则返回

{

    int count;   //统计相同的项的数目

    if(!items.empty())

    {

for(vector >::size_type ix=0;ix!=items.size();ix++)

       {

           count=0;

for(vector::size_type iy=0;iy!=items[ix].size();iy++)

           {

for(vector::size_type iz=0;iz!=item.size();iz++)

               {

                   if(item[iz]==items[ix].at(iy))

                   {

                      count++;

                   }

               }

           }

           if(count==item.size())     //表示存在

           {

              return 1;

           }

       }

     }

    return 0;

}

int main()

{

vector > datavec; //原始数据项集

vector > candidatevec; //候选项集

vector > frequentvec; //频繁项集

vector > bitmap; //判断某个项目在某一个事务中是否存在,存在则值为1,反之为0

  long trancount=0;   //原始事务总数

      char name1[50];

  ifstream file;

cout<<"选择要打开的文件:new1.txt new2.txt new3.txt"< cin>>name1;

  file.open(name1,ios::in);    //打开数据文件

  if(!file)        //检查文件是否打开成功

  {

cout<<"Fail to open data file!"<     return 1;

  }

  else

  {

     string temp;

vector item; //项集的临时vector 

     int begin,end;

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

     {

        trancount++;

        begin=0; 

         temp.erase(0,temp.find_first_not_of("\\r\\\n "));   //去除字符串首部的空格

       temp.erase(temp.find_last_not_of("\\r\\\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<<"Press Enter to continue the processing"; //pause

     getchar();

map item_map;

for(vector >::size_type ix=0;ix!=datavec.size();++ix)

     {

for(vector::size_type iy=0;iy!=datavec[ix].size();++iy)

        {

         items_count[datavec[ix].at(iy)]++;    //该项集的计数加

         item_map[datavec[ix].at(iy)]=1;       //表示该项目在该事务中存在,值为1,否则默认为0

        }

        bitmap.push_back(item_map);

        item_map.clear();      //这里一定要清空一下

     }

map::const_iterator map_it=items_count.begin();

cout<<"候选项集1:"<     while(map_it!=items_count.end())      //输出候选1项集

     {

cout<<"{"<first<<"}"<        map_it++;

     }

cout<<"Press Enter to continue the processing"; //pause

     getchar();

     map_it=items_count.begin();

cout<<"频繁1项集(minsup=2):"<     while(map_it!=items_count.end())          //频繁1项集

     {

if(map_it->second>minsup) //支持度大于2

        {

            cout.setf(ios::fixed);

         cout<<"{"<first<<"}"<<" 支持度:"<second< item.push_back(map_it->first);

            frequentvec.push_back(item);   //插入候选项集的vector中

            item.clear();    

        }

        map_it++;

     }

     if(!frequentvec.empty())   //判断频繁项集是否为空,为空则退出

     {

cout<<"Press Enter to continue the processing"; //pause

         getchar();

         int round=1;     //生成候选项集轮次

         int found;    //是否包含有非频繁的子集,为表示含有,有的话进行剪枝

         string tempstr;

vector tempvec;

         do

         {

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

vector >::size_type st=frequentvec.size();

            candidatevec.clear();         //清除上一轮的候选项集

for(vector >::size_type st1=0;st1            {

for(vector >::size_type st2=st1+1;st2                {

                    found=0;

                    item=mergeItem(frequentvec[st1],frequentvec[st2],round);    //调用函数合并生成下一轮的候选项集

                    if(!item.empty()&&!isExist(item,candidatevec))   //若经过判断处理后返回的vector不为空且还不存在该项集,则作为候选项集加入候选vector中

                    {

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

                        string teststr;

                        int testint;

                        tempvec=item;

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

                        while(next_permutation(tempvec.begin(),tempvec.end()))   //遍历所有的组合                        {

for(vector::size_type tempst=0;tempst!=tempvec.size();tempst++) //拼接出该字符串组合

                           {

                                tempstr+=tempvec[tempst];                                

                           }

for(map::const_iterator tempit=items_count.begin();tempit!=items_count.end();tempit++)

                           {

if(tempit->second                                {

if(tempstr.find(tempit->first)!=string::npos) //表示包含有非频繁子项集

                                   {

                                       found=1;

teststr=tempit->first;

testint=tempit->second;

                                       break;

                                   }

                                }

                           }

                           tempstr.erase();

                           if(found)   //包含非频繁子项集

                           {

                              break;

                           }

                           

                        }

                        if(!found)     //只有不包含有非频繁子项集才加入候选项集中,否则剪枝掉

                           candidatevec.push_back(item);

                        found=0;   //重置

                    }

                    

                }

            }

            frequentvec.clear();         //清除上一轮的频繁项集

            round++;

cout<<"候选"< for(vector >::size_type ix=0;ix!=candidatevec.size();++ix) //输出候选项集

            {

cout<<"{";

for(vector::size_type iy=0;iy!=candidatevec[ix].size();++iy)

               {

cout<               }

cout<<"}"<            }

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

            {

cout<<"候选"<            }

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

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

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

            int mark;    //为避免执行多余的字符串串接工作

for(vector >::size_type sx=0;sx!=candidatevec.size();++sx) //构造下一轮的频繁项集

            {

                mark=1;

                count=0;

for(vector >::size_type sy=0;sy!=bitmap.size();++sy)

                {

                    flag=1;       //初始化为1,表出现

for(vector::size_type sz=0;sz!=candidatevec[sx].size();++sz)

                    {

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

                       {

                           flag=0;

                       }

                       if(mark==1)   //只串接一次

                       {

                           tempstr+=candidatevec[sx].at(sz);  //串接字符串

                       }

                    }

                    

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

                    {

                       count++;

                    }

                    mark++;

                }

                

if(count>minsup) //支持度大于2

                {

                    frequentvec.push_back(candidatevec[sx]);        //插入频繁项集

                }

                items_count[tempstr]=count;       //对应该项集的计数值

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

                string tempstr2;

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

                {

for(vector::size_type tempst=0;tempst!=candidatevec[sx].size();tempst++) //拼接出该字符串组合

                     {

                         tempstr2+=candidatevec[sx][tempst];

                     }

                     items_count[tempstr2]=count;  //对应该项集的计数值

                     tempstr2.erase();

                }               

                tempstr.erase();

            }

cout<<"Press Enter to continue the processing"; //pause

            getchar();

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

            {

                 

cout<<"频繁"<                 for(int sx=0;sx!=frequentvec.size();++sx)      //输出频繁项集

                 {

                     cout.setf(ios::fixed);

cout<<"{";

for(vector::size_type sz=0;sz!=frequentvec[sx].size();++sz)

                     {

cout<                        tempstr+=frequentvec[sx].at(sz);  //串接字符串

                     }

cout<<"}";

cout<                     tempstr.erase();

                 }

cout<<"Press Enter to continue the processing"; //pause

                 getchar();

             }

             else

             {

cout<<"没有"<             }

         }while(!frequentvec.empty());   //频繁项集不为空,则循环继续

         file.close();

         return 0;

     }

     else

     {         

         return 0;

     }    //end of if(!frequentvec.empty()) 

  }//end of if(!file)

}

•实验结果:

文档

数据挖掘实验三应用 Apriori 算法挖掘频繁项集

实验三、应用Apriori算法挖掘频繁项集学院计算机科学与软件学院•实验目的:(1)熟悉VC++编程工具和Apriori频繁项集挖掘算法。(2)根据管理层的需求,确定数据挖掘的任务,明确数据挖掘的功能,也就是明确要挖掘什么。(3)由确定的数据挖掘任务,从实验一处理后的结果中,采用切块或切片等联机分析处理技术,选择出挖掘任务相关数据。(4)用VC++编程工具编写Apriori算法的程序,对任务相关数据运行Apriori算法,挖掘出所有的频繁项集。1.写出实验报告。•实验原理:1、Apriori算
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top