Apriori算法是常用的用于挖掘出数据关联规则的算法,它用来找出数据值中频繁出现的数据集合,找出这些集合的模式有助于我们做一些决策。比如在常见的超市购物数据集,或者电商的网购数据集中,如果我们找到了频繁出现的数据集,那么对于超市,我们可以优化产品的位置摆放,对于电商,我们可以优化商品所在的仓库位置,达到节约成本,增加经济效益的目的。
下面我们就对Apriori算法做一个总结。
1. 频繁项集的评估标准
什么样的数据才是频繁项集呢?也许你会说,这还不简单,肉眼一扫,一起出现次数多的数据集就是频繁项集吗!的确,这也没有说错,但是有两个问题,第一是当数据量非常大的时候,我们没法直接肉眼发现频繁项集,这催生了关联规则挖掘的算法,比如Apriori, PrefixSpan, CBA。第二是我们缺乏一个频繁项集的标准。比如10条记录,里面A和B同时出现了三次,那么我们能不能说A和B一起构成频繁项集呢?因此我们需要一个评估频繁项集的标准。
常用的频繁项集的评估标准有支持度,置信度和提升度三个。
支持度就是几个关联的数据在数据集中出现的次数占总数据集的比重。或者说几个数据关联出现的概率。如果我们有两个想分析关联性的数据X和Y,则对应的支持度为:
Support(X,Y)=P(XY)=number(XY)/num(AllSamples)
以此类推,如果我们有三个想分析关联性的数据X,Y和Z,则对应的支持度为:
Support(X,Y,Z)=P(XYZ)=number(XYZ)/num(AllSamples)
一般来说,支持度高的数据不一定构成频繁项集,但是支持度太低的数据肯定不构成频繁项集。
置信度体现了一个数据出现后,另一个数据出现的概率,或者说数据的条件概率。如果我们有两个想分析关联性的数据X和Y,X对Y的置信度为
Confidence(X⇐Y)=P(X|Y)=P(XY)/P(Y)
也可以以此类推到多个数据的关联置信度,比如对于三个数据X,Y,Z,则X对于Y和Z的置信度为:
Confidence(X⇐YZ)=P(X|YZ)=P(XYZ)/P(YZ)
举个例子,在购物数据中,纸巾对应鸡爪的置信度为40%,支持度为1%。则意味着在购物数据中,总共有1%的用户既买鸡爪又买纸巾;同时买鸡爪的用户中有40%的用户购买纸巾。
提升度表示含有Y的条件下,同时含有X的概率,与X总体发生的概率之比,即:
Li⇐Y)=P(X|Y)/P(X)=Confidence(X⇐Y)/P(X)
强关联规则, 提升度小于等于1则X⇐Y是无效的强关联规则 。一个特殊的情况,如果X和Y独立,则有Li(X⇐Y)=1,因为此时P(X|Y)=P(X)。
一般来说,要选择一个数据集合中的频繁数据集,则需要自定义评估标准。最常用的评估标准是用自定义的支持度,或者是自定义支持度和置信度的一个组合。
给出如下几种类型的关联规则的例子,并说明它们是否是有价值的。
高支持度和高置信度的规则:如牛奶 -> 面包,由于这个规则很明显,所以不具有价值;
高支持度和低置信度的规则:如牛奶->大米,由于牛奶、大米销售量都比较高,所以有高支持度。但是很多事务不同时包括牛奶和大米,所以置信度很低,不具有价值。;
低支持度和低置信度的规则:如可乐->洗衣粉,由于置信度低,所以不具有价值;
低支持度和高置信度的规则:如尿布->啤酒,虽然支持度低,不过置信度高,具有价值。
2. Apriori算法思想
对于Apriori算法,我们使用支持度来作为我们判断频繁项集的标准。Apriori算法的目标是找到最大的K项频繁集。这里有两层意思,首先,我们要找到符合支持度标准的频繁集。但是这样的频繁集可能有很多。第二层意思就是我们要找到最大个数的频繁集。比如我们找到符合支持度的频繁集AB和ABE,那么我们会抛弃AB,只保留ABE,因为AB是2项频繁集,而ABE是3项频繁集。那么具体的,Apriori算法是如何做到挖掘K项频繁集的呢?
Apriori算法采用了迭代的方法,先搜索出候选1项集及对应的支持度,剪枝去掉低于支持度的1项集,得到频繁1项集。然后对剩下的频繁1项集进行连接,得到候选的频繁2项集,筛选去掉低于支持度的候选频繁2项集,得到真正的频繁二项集,以此类推,迭代下去,直到无法找到频繁k+1项集为止,对应的频繁k项集的集合即为算法的输出结果。
可见这个算法还是很简洁的,第i次的迭代过程包括扫描计算候选频繁i项集的支持度,剪枝得到真正频繁i项集和连接生成候选频繁i+1项集三步。
我们下面这个简单的例子看看:
我们的数据集D有4条记录,分别是134,235,1235和25。现在我们用Apriori算法来寻找频繁k项集,最小支持度设置为50%。首先我们生成候选频繁1项集,包括我们所有的5个数据并计算5个数据的支持度,计算完毕后我们进行剪枝,数据4由于支持度只有25%被剪掉。我们最终的频繁1项集为1235,现在我们链接生成候选频繁2项集,包括12,13,15,23,25,35共6组。此时我们的第一轮迭代结束。
进入第二轮迭代,我们扫描数据集计算候选频繁2项集的支持度,接着进行剪枝,由于12和15的支持度只有25%而被筛除,得到真正的频繁2项集,包括13,23,25,35。现在我们链接生成候选频繁3项集,123, 125,135和235共4组,这部分图中没有画出。通过计算候选频繁3项集的支持度,我们发现123,125和135的支持度均为25%,因此接着被剪枝,最终得到的真正频繁3项集为235一组。由于此时我们无法再进行数据连接,进而得到候选频繁4项集,最终的结果即为频繁3三项集235。
3. Aprior算法流程
输入:数据集合D,支持度阈值α
输出:最大的频繁k项集
设定k=1
扫描事务数据库一次,生成频繁的1-项集
如果存在两个或以上频繁k-项集,重复下面过程:
[候选产生] 由长度为k的频繁项集生成长度为k+1的候选项集
[剪枝操作] 对每个候选项集,若其具有非频繁的长度为k的子集,则删除该候选项集
[支持度计算] 扫描事务数据库一次,统计每个余下的候选项集的支持度
[删除非频繁项集] 删除非频繁的候选项集,仅保留频繁的(k+1)-项集
设定k = k+1
如果Lk+1为空集,则算法结束
从算法的步骤可以看出,Aprior算法每轮迭代都要扫描数据集,因此在数据集很大,数据种类很多的时候,算法效率很低。
4. Aprior算法总结
Aprior算法是一个非常经典的频繁项集的挖掘算法,很多算法都是基于Aprior算法而产生的,包括FP-Tree,GSP, CBA等。这些算法利用了Aprior算法的思想,但是对算法做了改进,数据挖掘效率更好一些,因此现在一般很少直接用Aprior算法来挖掘数据了,但是理解Aprior算法是理解其它Aprior类算法的前提,同时算法本身也不复杂,因此值得好好研究一番。不过scikit-learn中并没有频繁集挖掘相关的算法类库。
购物篮分析只针对所有属性为二元布尔类型的数据集。如果数据集中的某个属性为连续型变量时,说明如何利用离散化的方法将连续属性转换为二元布尔属性。比较不同的离散方法对购物篮分析的影响。
首先利用等频、等宽等方法将连续属性离散化,然后将离散化后的每个区间映射为一个二元属性。离散化时,如果区间太宽,可能因为缺乏置信度而失去某些模式;如果区间太窄,则可能因为缺乏支持度而失去某些模式。
以下是一个商场所销售商品的价格清单(按递增顺序排列,括号中的数表示前面数字出现次数)1(2)、5(5)、8(2)、10(4)、12、14(3)、15(5)、18(8)、20(7)、21(4)、25(5)、28、30(3)。请分别用等宽的方法和等高的方法对上面的数据集进行划分。
- 等宽方法:划分为3个数据集,每个数据集的宽度为价格10。价格在1—10之间出现次数为13;价格在11—20之间出现的次数为24;价格在21—30之间出现的次数为13。
- 等高方法:划分为2个数据集,每个数据集的高度为出现的次数4。出现次数1—4之间的价格为1、8、10、12、14、21、28、30,共8个数据;出现次数5—8之间的价格为5、15、18、20、25,共5个数据。