WAP-Tree(Web Access Pattern Tree)算法和PLWAP-Tree(Pre-Order Linked WAP-Tree)算法是针对于序列模式进行挖掘的两种算法,其中PLWAP-Tree是对WAP-Tree算法的一个改进。
WAP-Tree算法是一种挖掘web访问日志的序列模式的算法,该算法首先把web访问的序列存储到一棵前缀树中(类似与FP-Tree),然后再基于WAP-Tree通过递归的构造中间书进行序列模式挖掘。
WAP-Tree算法概述:
①.扫描数据库,找出所有的频繁项目
②.再次扫描数据库,根据①中所得到的频繁项目找出每个事务的频繁序列,然后构造WAP-Tree
③.找条件后缀模式
④.利用③中得到的后缀模式进行构造中间条件WAP-Tree
⑤.重复③、④步骤,直到构造的条件WAP-Tree只有一个分支或者为空时为止
WAP-Tree算法示例(数据如表一,最小支持度为3,即要求支持度〉3):
图1:示例数据
步骤:
1、扫描原始数据,得到频繁项目:
扫描DB,得到各个项目的支持度 a:4 b:4 c:4 d:1 e:2 f:3 ,因为d、e、f 的支持度均<=3,所以将其剔除,故得到频繁项目:
a:4 b:4 c:4
2、再次扫描数据库,得到频繁序列,然后构造WAP-Tree
2.1 得到的频繁序列如图1的第三列所示
2.2 构造WAP-Tree的过程如图2所示
图2:构造WAP-Tree过程(其中每个节点的数字代表该节点出现的次数)
Header table:存储了每个频繁项目,每个频繁项目后面是一个链表,该链表中存储了该项目在WAP-Tree中出现的位置(以每个项目插入的顺序进行存储【注意这与PLWAP-Tree中Header table存储的方式不一样】)
3、找到条件后缀模式
在Head table中找到出现频度最低的项目进行挖掘:即选取C进行挖掘
3.1 找出C的前缀条件序列如下:(因为Header table中项目C的链表存储了C出现的位置,顺着链表既可以找到每个C在树中的位置,而不用遍历整棵树)
aba:2; ab:1; abca:1; ab:−1; baba:1; abac:1; aba:−1.
注:在WAP-Tree分支中,若某一项目的条件前缀序列中含有一个子序列(该子序列也是同一项目的条件前缀序列),则需要将同等数量子序列提取出来,因为其之前已经贡献过一次计数了。
例:在abcac中,第二个c的前缀序列是abca:1,但是由于其中ab是第一个c的前缀序列,所以为了避免ab序列的数量计数两次,所以便有了ab:-1序列
3.2 统计c的前缀序列中每个项目的支持度,得到如下:
a:4 b:4 c:2 (c的支持度小于等于3,故剔除)
3.3根据上一步得到的结果构造频繁序列
则频繁序列为:aba:2; ab:1; aba:1; ab:−1; baba:1; aba:1; aba:−1
4、利用上一步中得到的结果构造条件WAP-Tree树(如图3的(a)所示)
图3:基于项目c构造的WAP-Tree
然后重复算法的第 ③、④步,
根据图3(a),选择最小支持度的项目b,然后构造bc的条件WAP-Tree,如图3(b),然后图3(b)只有一个分支,则计算支持度后返回,然后构造ac的条件WAP-Tree如图3(c)所示,接着构造bac和aac的条件WAP-Tree,如图3(d)和如图3(e)所示。。。依次递归重复下去,最终得到的频繁模式项目集结果如下所示:
{c, aac, bac, abac, ac, abc, bc, b, ab, a, aa,ba, aba}
PLWAP-Tree算法:
其他算法存在的问题:
①类Apriori算法会产生大量的候选模式集合(特别是频繁序列模式很长的时候)
②WAP-Tree算法中递归的构造条件WAP-Tree将会十分费时
故因为WAP-Tree构造条件WAP-Tree费时的特点,提出了PLWAP-Tree算法,该算法将会避免条件WAP-Tree的构造。PLWAP-Tree算法是基于某个项目的后缀树进行挖掘(WAP-Tree算法是基于某个项目的前缀树进行挖掘)且PLWAP-Tree中的每个节点都有一个独一无二的编码,由于编码的存在,避免了构造条件WAP-Tree.
PLWAP-Tree算法伪代码如图4、5、6所示:
图4:算法整体流程图
图5:PLWAP-Tree构造算法
(从算法可以看出,其先构造PLWAP-Tree,然后以先序遍历的方式遍历该树构造先序链【WAP-Tree是在构造树的过成功,以节点插入的先后顺序构造先序链】)
图6:PLWAP-Tree的挖掘算法
PLWAP-Tree算法示例(同理利用图1所示数据,然后最小支持度同样为3):
1、扫描原始数据,得到频繁项目:
扫描DB,得到各个项目的支持度 a:4 b:4 c:4 d:1 e:2 f:3 ,因为d、e、f 的支持度均<=3,所以将其剔除,故得到频繁项目:
a:4 b:4 c:4
2、再次扫描数据库,得到频繁序列,然后构造PLWAP-Tree
2.1 得到的频繁序列如图1的第三列所示
2.2 构造的PLWAP-Tree如图7所示
图7:PLWAP-Tree的构造结果(已经插入先序链)
注:
节点命名规则:节点名:节点所对应项目出现的次数:节点的编码
编码规则:(1).根节点的编码为空 (2).root子节点的最左端节点编码为1,其他的子节点的最左端节点(左边第一个节点)为其父节点编码后增加1位1, (3). 其他节点,若该节点是其父节点的左边第二个节点,则在其父节点的编码后加上10,若是左边第三个节点则在其父节点上增加100,若是左边第四个节点,则在其父节点的后边增加1000,依次类推......
3、递归挖掘频繁序列
此步骤的挖掘按照图6,所示的算法。
3.1.挖掘以aa为开头的频繁序列的的过程如下图8所示:
图8:挖掘以aa开头的频繁序列的过程示意图
第一步调用R={Root} F=NULL
过程解析: ①找出先序表的L中每个事件找出后缀树,如图8(a)所示,
②把a序列(即a:{1,111,11101,101,10111})记为ei-sequence,把ei-sequence中的第一个节点(a:1)存入S,
③遍历ei-sequence,如果ei-sequence的节点ei是R 的后代并且不是S的后代,则 【根据节点的位置编码可以轻松判定某个节点是否是另一个节点的后代,而不用遍历树去判断】
则把该节点ei加入后缀树头节点集合R’
把ei的数量加入C
用ei 代替S
④ 如果C 大于λ 【判断是否大于支持度】
把 ei 添加到F 后形成F’ 并输出F’ (输出频繁模式)
对调用本身,传入参数R’,F’
Q:如何判断节点B是否是节点A的后代?
A:在节点A的编码后面加上1,判断节点B的编码的前N位是否与节点A后面加上1后的编码相同,相同则为后代,不同则不是。
例如:节点a:3:1、节点c:2:1111、节点b:1:1011
节点a:3:1编码后面加上1变成11,
节点c:2:1111的前两位与节点a:3:1变化后的编码相同,故节点c:2:1111是节点a:3:1的后代;
节点b:1:1011的前两位与节点a:3:1变化后的编码不同,故节点b:1:1011不是节点a:3:1的后代。
3.2. 挖掘以ab和ac为开头的频繁序列,如图9所示:
图9:挖掘以ab和ac为开头的频繁序列的过程示意图
过程解析如图8的过程解析
然后按照图8和图9的过程挖掘以b和c开头的频繁序列
最终挖掘出的结果是:{c, aac, bac, abac, ac, abc, bc, b, ab, a, aa,ba, aba}
注:本文的算法和插图来源于文章《MiningWeb Log Sequential Patterns with Position Coded Pre-Order LinkedWAP-Tree∗》