序列模式是频繁模式的一种特殊情况,它们的应用范围完全不一样!如:
购买物品 |
尿布、啤酒、可乐 |
面包、尿布、啤酒 |
上述购物清单是两个用户的购物清单,根据上面的清单,我们可以发现尿布和啤酒组合起来一起购买的情况较多,因此超市可以根据这样的频繁项集分析,将尿布和啤酒放在较近的地方,或者将尿布和啤酒同时促销等增加销量。
而序列模式如:
u1购买物品 |
电视 |
高清机顶盒 |
u2购买物品 |
电视、电冰箱 |
高清机顶盒、冰箱清洁剂 |
上述购物清单是两个用户不同时间前后两次的购物清单,可以发现高清机顶盒往往在某个用户购买电视机以后的某次购物中出现在下次的购物清单中,但往往很少出现机顶盒在购买电视机之前出现,这是因为电视机的购买历史带来了(促进了)机顶盒的销售,因此超市可以根据这样的频繁序列模式分析,将机顶盒推荐给购买了电视的用户,或者在电视热卖以后增加机顶盒的促销来增加销量。
很常见的是,我们可以用许多算法挖掘频繁模式如Apriori和FPGrowth等,而为了对含有时间顺序的数据集进行频繁模式的挖掘,就有了GSP和SPADE算法。
定义:序列模式挖掘,假定数据集D,有n个序列(Seq),每个Seq由多个事件(Event)组成,所有Event都是时间有序的。
若有一个Seq,它是数据集D的部分序列的子序列,那么它的支持度的计算方式为:
support(s) = s在n个序列中出现的次数
如果spport(s)>min_support,则我们可以把它称为频繁序列,或者序列模式。下面是两个常用的挖掘算法:
GSP算法其实就是一个类Apriori算法,它也就两个步骤:1.进行自连接 2.进行剪枝
序列如何进行自连接呢?有这样一个定义,即对于序列S1和S2,如果序列S1去掉第一项,与序列2去掉最后一项得到的序列相同,那么序列1和序列2就是可以连接的。把序列2的最后一项加入到序列1中,得到一个新的连接,即可以作为序列1和序列2连接的结果。
GSP算法的剪枝条件与Apriori算法的剪枝条件相同:
1.如果序列的支持度小于最小支持度,那么就会被剪掉
2.如果序列是频繁序列,则它的所有子序列必定是频繁序列;
我们假定数据集D有三组序列(SID=1, SID=2, SID=3),并假定min_support=2:
SID | EID | 项 |
1 | 1 | I1,I2 |
1 | 2 | I3 |
1 | 3 | I4 |
SID | EID | 项 |
2 | 1 | I2 |
2 | 2 | I3 |
SID | EID | 项 |
3 | 1 | I2 |
3 | 2 | I4 |
我们首先得到的候选序列为(接下来的表述中,尖括号<>表示里面的项有序,而圆括号()表示里面的项是出现在一个event中):
<I1>,<I2>,<I3>,<I4>
可以得到它们的支持度分别为:
<I1>:1
<I2>:3
<I3>:2
<I4>:2
进行剪枝,可以得到的序列模式为:
<I2>:3
<I3>:2
<I4>:2
然后再用前一步得到的序列模式,进行自连接,我们可以得到候选序列:
<I2,I2>:0
<I2,I3>:2
<I2,I4>:2
<I3,I2>:0
<I3,I3>:0
<I3,I4>:1
<I4,I2>:0
<I4,I3>:0
<I4,I4>:0
(I2,I3):0
(I2,I4):0
(I3,I4):0
进行剪枝,得到的序列模式为:
<I2,I3>:2
<I2,I4>:2
由于<I2,I3>去掉第一项得到<I3>,与<I2,I4>去掉最后一项得到<I2>,序列并不相同。所以它们是不能进行连接的,此时算法终止。最终得到的序列模式即为:
<I2,I3>,<I2,I4>
即如果用户购买了I2,则很有可能再购买I3;如果用户购买了I2,则很有可能再购买I4。
GSP算法很直白,但是也有缺点,就是每次计算序列的支持度时,都需要全表扫描数据集D。我们简单估计一下,假设数据集D的里面含有m个不同的项。假设第一步得到的单个序列候选集无需进行剪枝,那么由那个单个序列集合再进行自连接时,得到的序列个数为:m*m+m(m-1)/2个。(m*m个为有序的序列,m(m-1)/2为同时出现在某一个event的序列个数),那么此时需要进行的数据集D的扫描次数=(m*m+m(m-1)/2)*数据集D的记录数。一次候选集剪枝的全数据集D的扫描次数都非常之大。
针对上面的问题,就有了SPADE算法的提出。
SPADE算法在GSP算法的基础上,提出了ID_LIST的概念,来规避多次对数据集D进行全表扫描的问题。ID_LIST是一个(SID,EID)组成的集合。
我们用上面一个例子来推导一下,了解SPADE算法是如何做的。
第一轮的候选序列<I1>,<I2>,<I3>,<I4>,我们得到它们的ID_LIST:
I1
SID | EID |
1 | 1 |
I2
SID | EID |
1 | 1 |
2 | 1 |
3 | 1 |
SID | EID |
1 | 2 |
2 | 2 |
SID | EID |
1 | 3 |
3 | 2 |
这样我们可以很快的知道它们的支持度:
<I1>:1
<I2>:3
<I3>:2
<I4>:2
进行剪枝,可以得到的序列模式为:
<I2>:3
<I3>:2
<I4>:2
然后,我们再根据序列模式自连接得到本轮的候选集,以及候选集对应的ID_LIST(此时的ID_LIST可以由上一轮的ID_LIST得到),因为候选集包括:
<I2,I2>:0
<I2,I3>:2
<I2,I4>:2
<I3,I2>:0
<I3,I3>:0
<I3,I4>:1
<I4,I2>:0
<I4,I3>:0
<I4,I4>:0
(I2,I3):0
(I2,I4):0
(I3,I4):0
针对其中的<I2,I3>的ID_LIST进行举例子:
I2的ID_LIST含有3项(1,1),(2,1),(3,1);
而I3的ID_LIST有2项(1,2),(2,2);
那么我们可以知道,序列号相同,且I3在I2之后出现的有两项:
(1,1)(1,2)
(2.1)(2,2)
即可以得到<I2,I3>的ID_LIST:
SID | EID | EID |
1 | 1 | 2 |
2 | 1 | 2 |
所以,可以得到<I2,I3>的支持度为2。同样的第二轮会进行剪枝,得到序列模式:
<I2,I3>:2
<I2,I4>:2
由于<I2,I3>去掉第一项得到<I3>,与<I2,I4>去掉最后一项得到<I2>,序列并不相同。所以它们是不能进行连接的,此时算法终止。最终得到的序列模式即为:
<I2,I3>,<I2,I4>
其实可以看到,SPADE与GSP算法大体相同,只不过由于它多了一个ID_LIST记录,使得每一次的ID_LIST根据上一次的ID_LIST得到(从而得到支持度),而ID_LIST的规模是随着剪枝的不断进行,而规模逐渐缩小的。所以也就解决了GSP算法多次扫描数据集D问题。
(参考:http://blog.csdn.net/rongyongfeikai2/article/details/40478335)
原文地址:http://blog.csdn.net/scut_flyaway/article/details/42896957