Apriori算法原理及实现

***********************************************声明******************************************************

原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

由于各种原因,可能存在诸多不足,欢迎斧正!

*********************************************************************************************************

有这样一个故事:美国的妇女们经常会嘱咐她们的丈夫下班后为孩子买尿布,而丈夫在买完尿布后又要顺 手买回自己爱喝的啤酒,因此啤酒和尿布在一起被购买的机会很多。这个举措使尿布和啤酒的销量双双增加,并一直为众商家所津津乐道。"尿布和啤酒":关联规则的一个非常有名的故事。关联规则的是在一个数据集中找出项与项之间的关系,也被称为购物蓝分析。

提到关联规则,一个概念很重要?频繁项集:支持度大于等于最小支持度项集。有两个比较重要的度量参数:

1)、支持度

支持度是交易集同时包含X和Y的交易数与总交易数|D|之比。

support(X?Y)=count(X?Y)/|D|

支持度反映了X、Y同时出现的概率。关联规则的支持度等于频繁集的支持度。

2)、置信度

置信度是指包含X和Y的交易数与包含X的交易数之比。即:

confidence(X?Y)=support(X?Y)/support(X)

可信度反映了如果交易中包含X,则交易包含Y的概率。一般来说,只有支持度和可信度较高的关联规则才是用户感兴趣的。

关联规则寻找频繁项集的Apriori算法,Apriori算法是挖掘布尔型关联规则频繁项集的最为经典、最为基本的算法,该算法需要不断寻找候选集,然后剪枝即去掉包含非频繁子集的候选集,时间复杂度由暴力枚举所有子集的指数级别O(n^2) 降为多项式级别,多项式具体系数是底层实现情况而定 。Apriori算法基于这样的事实:算法使用频繁项集性质的先验知识。Apriori使用一种称作逐层搜索的迭代方法,k-项集用于探索(k+1)-项集。首先,找出频繁1-项集的集合。该集合记作L1。L1用于找频繁2-项集的集合L2,而L2用于找L3,如此下去,直到不能找到频繁k-项集。Ariori算法有两个主要步骤:

1、连接

利用已经找到的Lk,通过两两连接得出Ck+1,注意进行连接的Lk[i],Lk[j],必须有k-1个属性值相同,然后另外两个不同的分别分布在Lk[i],Lk[j],这样的求出的Ck+1为Lk+1的候选集。

2、剪枝

候选集Ck+1中的并不都是频繁项集,必须剪枝去掉,越早越好以防止所处理的数据无效项越来越多。只有当子集都是频繁集的候选集才是频繁集,这是剪枝的依据.

//Apriori.h
<span style="font-family:Verdana;font-size:14px;"><span style="font-family:Verdana;font-size:14px;"></span></span><pre name="code" class="cpp">/**
 * Created by xujin on 2014/12/1.
   All Rights Reserved,but you can use this program.
 */

#ifndef APRIORI_H#define APRIORI_H#include"Transaction.h"#include"TransactionSet.h"class CApriori{private:double m_dMinConfidence;double
m_dMinSupport;int m_nSize; int m_nMinConfidence;int m_nMinSupport;int m_nK;CTransactionSet *m_pCTransactionSet;CTransactionSet *m_pCDateCandidateSet;private:void eraseCandidateSet();bool hasInfrequentSubSet(vector<string> &tVecCandidateSet);void aprioriGen();
void findFrequent1ItemSet();bool isFrequentSet(vector<string> &tVecCandidateSet);bool isExist(vector<string> &tVecCandidateSet);public:CApriori(double tMinCon,double tMinSup,int tK,CTransactionSet *tPDaSet);void findFrequentKItemSet();void print();};#endif


//Apriori<span style="font-family:Verdana;">.cpp
<span style="font-family:Verdana;font-size:14px;"><span style="font-family:Verdana;font-size:14px;"></span></span></span><pre name="code" class="cpp">/**
 * Created by xujin on 2014/12/1.
   All Rights Reserved,but you can use this program.
 */

#include"Apriori.h"CApriori::CApriori(double tMinCon,double tMinSup,int tK,CTransactionSet *tPDaSet){this->m_dMinConfidence=tMinCon;this->m_dMinSupport=tMinSup;this->m_nK=tK;this->m_pCTransactionSet = tPDaSet;this->m_nSize = tPDaSet->getSize();this->m_nMinConfidence=this->m_dMinConfidence*this->m_nSize;this->m_nMinSupport=this->m_dMinSupport*this->m_nSize;//cout<<"m_nMinConfidence
m_nMinSupport m_nK m_nSize"<<m_nMinConfidence<<" "<<m_nMinSupport<<" "<<m_nK<<" "<<m_nSize<<endl;this->m_pCDateCandidateSet=new CTransactionSet();}bool CApriori::hasInfrequentSubSet(vector<string> &tVecCandidateSet){bool bRet=false;if(this->m_pCDateCandidateSet!=NULL){for(vector<string>::iterator
out=tVecCandidateSet.begin();out!=tVecCandidateSet.end();++out){vector<string>tmp;tmp.clear();for(vector<string>::iterator in=tVecCandidateSet.begin();in!=tVecCandidateSet.end();++in){if(*out!=*in){tmp.push_back(*in);}}if(!this->m_pCDateCandidateSet->isContain(tmp)){bRet=true;break;}}}return
bRet;}void CApriori::aprioriGen(){vector<string> can;CTransactionSet *CandidateSet=new CTransactionSet();for(size_t i=0;i<(this->m_pCDateCandidateSet->getSize());++i){for(size_t j=0;j<(this->m_pCDateCandidateSet->getSize());++j){if(i!=j){can.clear();if(this->m_pCDateCandidateSet->combineFrequentSet(i,j,can)){if(!this->hasInfrequentSubSet(can)&&!CandidateSet->isExist(can))CandidateSet->addTransaction(CTransaction(can));}}}}eraseCandidateSet();this->m_pCDateCandidateSet=CandidateSet;}void
CApriori::eraseCandidateSet(){for(vector<CTransaction>::iterator iter=this->m_pCDateCandidateSet->getVeCTransaction().begin();iter!=this->m_pCDateCandidateSet->getVeCTransaction().end();++iter){iter->getVecItem().clear();}this->m_pCDateCandidateSet->getVeCTransaction().clear();delete
this->m_pCDateCandidateSet;this->m_pCDateCandidateSet=NULL;}bool CApriori::isFrequentSet(vector<string> &tVecCandidateSet){int sup=this->m_pCTransactionSet->getSupportCount(tVecCandidateSet);if(sup<m_nMinSupport)return false;return true;}void CApriori::findFrequent1ItemSet(){for(vector<CTransaction>::iterator
iter=this->m_pCTransactionSet->getVeCTransaction().begin();iter!=this->m_pCTransactionSet->getVeCTransaction().end();++iter){for(vector<string>::iterator strIter=iter->getVecItem().begin();strIter!=iter->getVecItem().end();++strIter){vector<string> vec1Itemset;vec1Itemset.push_back(*strIter);if(this->isFrequentSet(vec1Itemset)){if(!this->isExist(vec1Itemset))
m_pCDateCandidateSet->addTransaction(CTransaction(vec1Itemset));}}}}void CApriori::findFrequentKItemSet(){this->findFrequent1ItemSet();//this->print();for(int i=2;i<=this->m_nK;++i){this->aprioriGen();// this->print();if(this->m_pCDateCandidateSet->getVeCTransaction().size()==0)return
;//cout<<"*********"<<endl;for(vector<CTransaction>::iterator iter=this->m_pCDateCandidateSet->getVeCTransaction().begin();iter!=(this->m_pCDateCandidateSet->getVeCTransaction().end());){int sup=this->m_pCTransactionSet->getSupportCount(iter->getVecItem());//cout<<"&&&&sup="<<sup<<"
m_nMinSupport="<<m_nMinSupport<<endl;if(sup<this->m_nMinSupport){iter=this->m_pCDateCandidateSet->getVeCTransaction().erase(iter);// cout<<"!!!!!!!!!"<<endl;}else ++iter;// cout<<"^^^^&&&&sup="<<sup<<" m_nMinSupport="<<m_nMinSupport<<endl;}// cout<<"&&&&&&"<<endl;}}void
CApriori::print(){m_pCDateCandidateSet->print();}bool CApriori::isExist(vector<string> &tVecCandidateSet){ if(this->m_pCDateCandidateSet->isExist(tVecCandidateSet))return true;return false;}


Apriori算法的主要瓶颈在于不断寻找候选项集,可不可以找到一种不用频繁寻找候选项集的算法呢?而且当待挖掘的数据很大进而需要存储在数据库中时,Apriori算法还有一个无可回避的问题就是每次都要扫描数据库,涉及大量I/O操作,比较耗时(当然可以不用数据库)。

由于时间有限,在写博文的过程中参考过一些文献,在此表示感谢;同时鉴于水平原因,你难免有不足之处,欢迎斧正!

时间: 2024-10-18 17:52:08

Apriori算法原理及实现的相关文章

Apriori算法原理总结

Apriori算法是常用的用于挖掘出数据关联规则的算法,它用来找出数据值中频繁出现的数据集合,找出这些集合的模式有助于我们做一些决策.比如在常见的超市购物数据集,或者电商的网购数据集中,如果我们找到了频繁出现的数据集,那么对于超市,我们可以优化产品的位置摆放,对于电商,我们可以优化商品所在的仓库位置,达到节约成本,增加经济效益的目的.下面我们就对Apriori算法做一个总结. 1. 频繁项集的评估标准 什么样的数据才是频繁项集呢?也许你会说,这还不简单,肉眼一扫,一起出现次数多的数据集就是频繁项

Apriori算法--关联规则挖掘

我的数据挖掘算法代码:https://github.com/linyiqun/DataMiningAlgorithm 介绍 Apriori算法是一个经典的数据挖掘算法,Apriori的单词的意思是"先验的",说明这个算法是具有先验性质的,就是说要通过上一次的结果推导出下一次的结果,这个如何体现将会在下面的分析中会慢慢的体现出来.Apriori算法的用处是挖掘频繁项集的,频繁项集粗俗的理解就是找出经常出现的组合,然后根据这些组合最终推出我们的关联规则. Apriori算法原理 Aprio

FP Tree算法原理总结

在Apriori算法原理总结中,我们对Apriori算法的原理做了总结.作为一个挖掘频繁项集的算法,Apriori算法需要多次扫描数据,I/O是很大的瓶颈.为了解决这个问题,FP Tree算法(也称FP Growth算法)采用了一些技巧,无论多少数据,只需要扫描两次数据集,因此提高了算法运行的效率.下面我们就对FP Tree算法做一个总结. 1. FP Tree数据结构 为了减少I/O次数,FP Tree算法引入了一些数据结构来临时存储数据.这个数据结构包括三部分,如下图所示: 第一部分是一个项

关联分析算法-Apriori算法

Apriori算法原理一:如果某个项集是频繁的,那么它的所有子集也是频繁的,如果一个项集是非频繁的,那么它的所有超集也是非频繁的. Apriori算法原理二:如果某条规则并不满足最小可信度要求,那么该规则的所有子集也不会满足最小可信度要求. 注:若所有项集为树形结构,子集是上一层,超集是下一层.

Apriori算法的java实现

介绍 Apriori算法是一个经典的数据挖掘算法,Apriori的单词的意思是"先验的",说明这个算法是具有先验性质的,就是说要通过上一次的结果推导出下一次的结果,这个如何体现将会在下面的分析中会慢慢的体现出来.Apriori算法的用处是挖掘频繁项集的,频繁项集粗俗的理解就是找出经常出现的组合,然后根据这些组合最终推出我们的关联规则. Apriori算法原理 Apriori算法是一种逐层搜索的迭代式算法,其中k项集用于挖掘(k+1)项集,这是依靠他的先验性质的: 频繁项集的所有非空子集

数据挖掘算法——Apriori算法

Apriori算法 首先,Apriori算法是关联规则挖掘中很基础也很经典的一个算法. 所以做如下补充: 关联规则:形如X→Y的蕴涵式,其中, X和Y分别称为关联规则的先导(antecedent或left-hand-side, LHS)和后继(consequent或right-hand-side, RHS) .其中,关联规则XY,存在支持度和信任度. 支持度:规则前项LHS和规则后项RHS所包括的商品都同时出现的概率,可以理解为LHS和RHS商品的交易次数/总交易次数. 置信度:在所有的购买了左

第十四篇:Apriori 关联分析算法原理分析与代码实现

前言 想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事. 那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢? 这就是关联分析所要完成的任务了. 本文将讲解关联分析领域中最为经典的Apriori算法,并给出具体的代码实现. 关联分析领域的一些概念 1. 频繁项集: 数据集中经常出现在一起的物品的集合.例如 "啤酒和尿布" 2. 关联规则: 指两个物品集之间可能存在很强的关系.例如 "{啤酒} -> {尿布}"

Apriori 关联分析算法原理分析与代码实现

前言 想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事. 那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢? 这就是关联分析所要完成的任务了. 本文将讲解关联分析领域中最为经典的Apriori算法,并给出具体的代码实现. 关联分析领域的一些概念 1. 频繁项集: 数据集中经常出现在一起的物品的集合.例如 "啤酒和尿布" 2. 关联规则: 指两个物品集之间可能存在很强的关系.例如 "{啤酒} -> {尿布}"

机器学习(八)—Apriori算法

摘要:本文对Apriori算法进行了简单介绍,并通过Python进行实现,进而结合UCI数据库中的肋形蘑菇数据集对算法进行验证. “啤酒与尿布”的例子相信很多人都听说过吧,故事是这样的:在一家超市中,人们发现了一个特别有趣的现象,尿布与啤酒这两种风马牛不相及的商品居然摆在一起.但这一奇怪的举措居然使尿布和啤酒的销量大幅增加了.这可不是一个笑话,而是一直被商家所津津乐道的发生在美国沃尔玛连锁超市的真实案例.原来,美国的妇女通常在家照顾孩子,所以她们经常会嘱咐丈夫在下班回家的路上为孩子买尿布,而丈夫