首先,要感谢谭武和张朋博同学的PPT,怀念以前一起学习数据挖掘十大算法的时光!
1.关联挖掘例子
啤酒和尿布的故事:
在一家超市中,人们发现了一个特别有趣的现象:尿布与啤酒这两种风马牛不相及的商品居然摆在一起。但这一奇怪的举措居然使尿布和啤酒的销量大幅增加了。这可不是一个笑话,而是一直被商家所津津乐道的发生在美国沃尔玛连锁超市的真实案例。原来,美国的妇女通常在家照顾孩子,所以她们经常会嘱咐丈夫在下班回家的路上为孩子买尿布,而丈夫在买尿布的同时又会顺手购买自己爱喝的啤酒。这个发现为商家带来了大量的利润,但是如何从浩如烟海却又杂乱无章的数据中,发现啤酒和尿布销售之间的联系呢?这又给了我们什么样的启示呢?
购物篮例子:
23的买了cheese。
Bread⟹cheese,形如:如果…那么就…(If…Then…),前者为条件,后者为结果,用来描述二者相关性。那么,Bread⟹cheese就是一条规则,我们至少可以总结50%的顾客可以支持该规则,因为50%的人同时有两件物品,并且有23的可信度。
关联规则挖掘用于寻找给定数据集中项之间的有趣的关联或相关关系。关联规则揭示了数据项间的未知的依赖关系,根据所挖掘的关联关系,可以从一个数据对象的信息来推断另一个数据对象的信息。而找出关联规则就是Apriori算法要做的事。
2.相关基本概念
项集:
令I={i1,i2,...,in}表示一个项集,显然这是一个n项集,因为该项集中有n个元素,项集的支持度计数如下:
σ(I)=|{ti|I⊆ti,ti⊆T}|
其中
T表示所有事务集,也就是所有的样本;ti表示总事务集
T中的一个子集,I表示要计算支持度计数的项集。其实就是计算包含项集
I的样本的个数。
{outlook(天气状况),temperature(温度),humidity(湿度),windiy(是否刮风)},,其结果就是是否出去游玩
play。先给出各种属性的取值,然后各处一些项集举例,从单项集到四项集的部分举例。
关联规则:
关联规则是一种蕴含形式X⟹Y,其中X⊆I,Y⊆I,并且X⋂Y=∅,X,Y都是项集,关联规则就是挖掘项集之间的联系性。
支持度:
是指既包含X 又包含Y的事务占全体事务的百分比即:
support(X,Y)=σ(X⋃Y)N
其中
N是总的事务的个数,也就是总的样本个数。本质上就是既包含项集X又包含项集Y的样本数占总样本数的百分比。
置信度:
是指包含项集X的事务中也包含项集Y的事务所占的比例,即:
Confidence(X,Y)=σ(X⋃Y)σ(X)
其实相当于条件概率。
minsup:
表示最小支持度
minconf:
表示最小置信度
频繁项集:
支持度不小于minsup的项集,项集里项的数量为项的大小,大小为k的项集被称为k-项集。
对于一个事务集T,Apriori的任务就是产生所有不小于用户给定的最小支持度(minsup)和最小置信度(minconf)的关联规则。
超集:
如果一个集合s2的每一个元素都在s1中,且s1中可能包含s2中没有的元素,s1就是s2的超集,简单来说就是父集
3.Apriori算法
算法包括两个组成部分:
Apriori=>{1.寻找频繁项集2.推导关联规则
1.寻找频繁项集:
Apriori性质:项集的反向单调性,即频繁项集的所有非空子集肯定也是频繁的。例如,在购物篮例子中,每个包含 {Apple,bread,dove} 的事务也包含{bread,dove},如果{Apple,bread,dove}是频繁项集,那么根据频繁项集的定义,{bread,dove}也必定是频繁项集。转换一下思维,如果一个子集是非频繁的,那么它的超集也一定是非频繁的。这在Apriori 算法里面很重要。
F(k)表示大小为k的频繁项集的集合,C(k)表示候选集,即可能成为大小为k的频繁项集的k项集,两者之间的关系式:
F(k)⊆C(k)
利用 Apriori 算法反向单调性的性质,我们可以使用频繁
(k−1)项集
F(k−1)来寻找频繁
k项集F(k),求解时分两个过程:连接步和剪枝步。
连接步:
F(k−1)与其自身进行连接,产生候选项集C(k)。F(k−1)中某个元素与其中另一个元素可以执行连接操作的前提是它们中有(k−2)个项是相同的。也就是只有一个项是不同的。
dove,egg与egg,bread连接之后产生的3项集是{egg,dove,bread},而项集{egg,bread} 与 {dove,apple}不能进行连接操作。
剪枝步:
候选集 C(k)中的元素可以是频繁项集,也可以不是。 但所有的频繁 k项集一定包含在C(k)中,所以, C(k) 是F(k)的超集。扫描事物集T,计算C(k)中每个候选项出现的次数,出现次数大于等于最小支持度与事务集 T中事务总数乘积的项集便是频繁项集(这里的最小支持度指的是概率,实际中我们经常直接将最小支持度看成乘积后的结果),如此便可确定频繁k项集F(k)了。
C(k)很大,所以计算量也会很大。为此,需要进行剪枝,即压缩C(k),删除其中肯定不是频繁项集的元素.依据就是前面提到的 Apriori 单向单调性的性质:如果一个子集是非频繁的,那么它的超集也一定是非频繁的。这在 Apriori 算法里面很重要。如此,如果一个候选(k−1)子集不在 F(k−1) 中,那么该候选 k项集也不可能是频繁的,可以直接从 C(k) 中删除。如下图所示:
下图是一组求解频繁项集的过程:
在单项集中,只有{D}不满足最小支持度,所以将其剪去。
在2项集中,{A,B},{A,E}都不满足最小支持度,所以将其剪去。
在3项集中,{A,B,C},{A,C,E}都不满足最小支持度,所以将其剪去。
2.推导关联规则:
枚举每个频繁项集f的每个非空子集a,如果support(f)除以support(a)不小于minconf,即生成一条规则a⟹(f−a)。 即,如果:
confidence(a,f−a)=σ(a⋃f−a)σ(a)=σ(f)σ(a)>=minconf
那么规则
a⟹(f−a)成立。
{{A,C},{B,C},{B,E},{C,E}},其可能的规则及相应的置信度如下图所示:
频繁3项集为{{B,C,E}},其可能的规则及相应的置信度为:
4.性能分析
Apriori算法的运行时间主要是由minsup决定的,当minsup变小时,运行时间会指数倍的增长,minconf和事务数量所起的作用相对较小。
在寻找规则时,minsup设定得过高虽然可以在较短的时间内获得少量关联规则,但其中很多规则都是平凡的。为了找到更有意义的规则,可以取得较小的minsup,但这可能导致不可接受的运行时间和数量庞大的关联规则。所以为了寻找有意义的规则必须找到更高效的算法
5.AprioriTid算法
CK¯¯¯¯¯,它的每个元素都是<TID,Item><script type="math/tex" id="MathJax-Element-31655"> </script>的形式,TID是事务的标志符,Item是事务TID中一个潜在的k项集的标识符,如果k=1, C1¯¯¯¯就是数据集T,只是T中的每个项i被 {i}代替。
Ck¯¯¯¯会变得比数据集小,因为一些事务可能不包含任何候选k项集,这种情况下Ck¯¯¯¯
其实本质上这种提升是在遍历事务T上进行了改进。之前我们每次求支持度,都得遍历整个事务T,然后求解候选集中所有可能项集的支持度。但是,其中有一些事务(样本)其实一直都是没有用的,没有包含任何频繁项集,我们每次计算都考虑这些事务没有任何意义,反而影响性能。而PrioriTID就是在这里进行了改进,通过维护一个TID列表,删除不需要考虑的事务,快速的计算出支持度。
以下面的例子为例:
假设最小支持度(minsup)为314。
如果图示,最开始根据总事务T构造出C1¯¯¯¯,从中可以得到单频繁项集为{a},{c},{d},{f},{g}。
根据之前求得的单频繁项集,我们可以构造出可能的2频繁项集,得到候选集C2,此时我们先遍历事务T,将不包含候选集的事务直接删除,所以被删除的事务的TID集合为{002,007,010,011,013},然后我们在计算候选集中各可能2频繁项集的概率,如下图所示:
然后根据F2,即2频繁项集构造可能的3频繁项集候选集C3,然后再遍历总事务T,继续进行剔除,被删除的事务的TID集合为{001,003,005,006,008,0012},只剩下最后三个了,最后重复这个过程,可以得到3频繁相机为{c,d,f}。
改进之处就是不再是每次都遍历所有的事务来求支持度,而是通过维护一个含有TID的列表,只保留可能的事务,来快速的求解可能的频繁集项。