【转】基于STL的关联规则 Apriori 算法的设计与实现

   关联规则association rule mining是众多“规则类”数据挖掘方法中的一种,对于关联规则的基本理论(假定读者已经了解)不在这里详细叙述,下面主要就算法的设计进行描述。
    Apriori算法的主要思想:
    1、根据Apriori性质“频繁项集的子集一定是频繁项集,非频繁项集的超集一定是非频繁项集”构造候选项集,然后通过遍历事务数据库来计算候选项集的支持度,得到频繁项集;
    2、由频繁项集生成关联规则。
    我认为,关联规则在理论上是比较简单的,相信很多人都会有这种感觉,但要真正做算法的设计与实现,反而是相当有难度的。问题的关键是:无法设计出频繁项集(一种适合1-项集、2-项集...n-项集的通用的数据结构)、规则的合理的数据结构。没有这两个数据结构,要实现关联规则就是“纸上谈兵”、或许是“雾里看花”也说不准。
      规则的数据结构比较好设计,一条规则无非就是包含这么几个成员(规则的条件、结论,支持度,可信度,提升度),因此一条规则可以用一个结构体(rule)表示:
typedef struct
{
  char condition[80];
  char conclusion[80];
  double sup;
  double conf;
  double lift;
}rule;
      所有的规则,可以看作是这个结构体的列表(list<rule> lst_rule)或可变数组(vector<rule> vt_rule)。
/*  anything,send me email datamining@163.com my QQ 275869936
*/
        项集的数据结构就比较复杂了。先对项集的结构和用处描述一下,让我们对它有一个整体了解。
      项集和每个事务的项的集合是类似的,都是几个项的集合{a,b,c,d,e,g...},元素(项)的个数为1...n(n-项集的情况)。
      项集的用处:
        1、由两个频繁n项集连接为一个侯选n+1项集
      2、在计算候选项集的支持度的时候,判断某个候选项集是否在当前的事务中(辅助函数2)。
      这就要求项集的数据结构必须能够容纳n个,同时也能容纳n+1个项,即项集的数据结构必须适应项个数的变化.
        在这里,我给出项集的一种数据结构包含两部分:一、存储项的集合的字符串(同时也适合事务);二、支持计数。
  可以采用map<string,int> 存储,第一个参数为字符串,即STL中的string,项集(或事务)以字符串形式保存,其中项与项之间以符号"|"间隔,如由项a,b,c构成的项集,表示为string m_Itemset="a|b|c" 格式。使用的时候,由辅助函数1,可根据"|"对字符串m_Itemset进行拆分,将每一个项存储到 vector<string> vt_itemset中,vector中的每个元素为一个项。
      第二个参数为支持计数。
     
  下面我们来讨论一下第二步,即由频繁项集生成规则,这一步的程序实现在论文中很少提及,大家都主要讨论第一步,即生成频繁项集,可能是因为改进第一步对于提高apriori性能是至关重要的。
    一个n-项集可以生成2的n次方减2条规则(每一条规则的条件和结论的项的集合是整个项集中的项,即n个项)【方法1】,在这里不要考虑多了,如每一个n-项集包含n个n-1项集,每一个n-1项集也可以生成2的n-1次方减2条规则。原因是我们的频繁项集中包含频繁1-项集、频繁2-项集...直到频繁n-项集(而不是只存储最大长度频繁项集),只要我们按照【方法1】对每一个频繁项集都生成其对应的规则,就得到了所有的规则。
 
 
辅助函数1:
/*
函数调用举例:
m_strSource="a|b|c";//输入参数
substr="|";  //输入参数
vector<string> vItem;
GetItemsFromString(m_strSource,vItem,substr);
vItem[0]="a";  //输出参数
vItem[1]="b";
vItem[2]="c";
*/
void GetItemsFromString(string &m_strSource,vector<string> &vItem,string substr)
{
 vItem.clear();
 int j;
 int i=m_strSource.find(substr,0);
 
 if (i==-1)
 {
  //m_strSource is a Item
  vItem.push_back(m_strSource);
 }
 else
 {
  string m_strTemp=m_strSource.substr(0,i);
  vItem.push_back(m_strTemp);
  
  while(i!=-1)
  {
   j=m_strSource.find(substr,i+1);
   
   if(j==-1)
   {
    m_strTemp=m_strSource.substr(i+1,m_strSource.size()-i-1);
    vItem.push_back(m_strTemp);
   }
   else
   {
    m_strTemp=m_strSource.substr(i+1,j-i-1);
    vItem.push_back(m_strTemp);
   }
   
   i=j;
  } //end of while
 }//end of else
}
辅助函数2:判断候选项集v1是否在事务v2中

bool IsIn(const vector<string> &v1,const vector<string> &v2)
{
 int nSize1=v1.size();
 int nSize2=v2.size();
 
 for(int i=0;i<nSize1;i++) //for1
 {
  bool m_bFlag1=false;
  for(int j=0;j<nSize2;j++)  //for2
  {
   if(v1[i]==v2[j])
   {
    m_bFlag1=true;
    break;
   }
   
  }// end of for2
  
  if (!m_bFlag1)
   return false;
  
 }// end of for1
 
 return true;
 
}

 

有了这两个数据结构和辅助函数,相信你能够设计出你的关联规则挖掘算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值