system: [SYSTEM]

user: 3. 频繁情节挖掘算法MANEPI 3.1. 共享前缀树 由于许多频繁情节具有相同的前缀，为节省存储空间，算法采用共享前缀树存储频繁情节。共享前缀树SPT (Shared Prefix Tree)是一棵有向根树，树中的每个结点N a 表示为一个四元组(label， mo， mano， children)，其中：label为结点N a 对应的事件类型，根结点的label为空，从根结点深度遍历到结点N a 的路径上所有label的串接表示频繁情节a；mo为结点N a 对应的频繁情节a的最小发生集，根结点的mo为空；mano为结点N a 对应的频繁情节a的最小且非重叠发生集，根结点的mano为空；children为指向结点N a 的孩子结点的指针，且这些指针按照所指孩子结点的label的字典序排列，所有叶结点的children为空。不难看出，SPT中非根结点对应的频繁情节是其所有孩子结点对应的频繁情节的前缀，共享前缀树由此而得名。 3.2. 算法MANEPI描述 算法MANEPI的基本思想是：首先单遍扫描给定事件流，从中发现所有频繁1-情节；然后对已发现的一个频繁i-情节a和一个频繁1-情节e进行串接，形成一个长度为i+1的新情节concat(a，e)，这个过程称为以a为前缀的一次情节增长。若concat(a，e)的支持度小于给定的支持度阈值，则concat(a，e)为非频繁情节，由定理1可知，concat(a，e)的任何超情节也是非频繁的，因而就无须以concat(a，e)为前缀进行情节增长；反之，若concat(a，e)的支持度大于等于给定支持度阈值，则concat(a，e)为频繁情节，算法接着以concat(a，e)为前缀递归地进行下一次情节增长，整个算法的终止条件是没有任何情节可以增长。下面是MANEPI的伪代码。 AlgorithmMANEPI(S， min_sup) Input: S: an event stream = <(E 1 ，t 1 )， (E 2 ，t 2 )， ∙∙∙， (E n ，t n )>; min_sup: a support threshold Output: SPT: a tree which stores all frequent episodes within S 1: Create SPT with simply a root node 2: Scan S once to find all frequent 1-episodes and Sort them in lexicographical order 3: For each frequent 1-episode edo 4: Create node N e as a child of the root 5: For each frequent 1-episode edo 6: MineGrow (N e ) Procedure Mine Grow (N a ) Input: N a : the node to be expanded Objective: find all frequent episodes with prefix a 1: For each 1-episode e do 2: Let b = concat(a，e) 3: Let b.mo = ComputeMO(a，e) 4: Let b.mano = ComputeMANO(b) 5: If b.sup ≥ min_sup 6: Create node N b as a child of N a 7: MineGrow(N b ) 3.3. 情节增长 MANEPI的核心是情节增长MineGrow，该过程的关键是如何计算一个新情节的支持度，具体而言，就是如何根据已发现的频繁i-情节a和频繁1-情节e来发现新情节concat(a，e)的所有最小且非重叠发生组成的最大集合。直观上，可以基于a.mano和e.mano来构造concat(a，e).mano。然而，由于在某些情形下a可能存在多个a.mano，无论选择哪一个a.mano，都有可能导致concat(a，e)的一些最小且非重叠发生丢失，从而也就不能发现所有的频繁情节。 例如，设S = <(A，1)， (A，2)， (B，3)， (D，4)， (A，5)， (C，6)， (B，7)， (E，8)， (A，9)， (C，10)， (B，11)， (A，12)， (C，13)>，a = ，e = ，b = concat(a，e)，表1列出了基于S上所有可能的a.mano进行情节增长的两种情形。 从表1中可以看出，无论选择哪一个a.mano，都不能得到正确的b.mano，因为两种情形下的|b.mano|都等于1，但事实上|b.mano| = |{[1，3]， [5，11]}| = 2，若min_sup = 2，则丢失了频繁情节b。可见，挖掘频繁情节时，若在SPT中只保存结点的mano，则不足以进行正确的情节增长，可能会导致部分频繁情节的丢失。为此，算法将情节增长分为两步实施：第一步，通过单遍扫描a.mo和e.mo得到concat(a，e).mo，这三个最小发生集均是唯一的；第二步，通过单遍扫描concat(a，e).mo得到最早出现的concat(a，e).mano。因为concat(a，e).mo保存了concat(a，e)的所有最小发生，所以由concat(a，e).mo得到的最早出现的concat(a，e).mano不会丢失concat(a，e)的任何最小且非重叠发生。由于a.mo和e.mo已将给定的事件流分割成有限个区间，所以基于这些有限的区间进行的情节增长避免了对给定事件流的多遍扫描。另外，SPT中每个结点的mano只是保存了指向该结点mo中相应最小发生的指针。下面是情节增长(包括两个子过程)的伪代码。 SubProcedure Compute MO(a，e) Input: a: a frequent i-episode with its mo; e: a frequent 1-episode with itsmo Output: concat(a，e).mo: the moof concat(a，e) 1: Letconcat(a，e).mo = f 2: Let i = 1 3: For each occurrence [t′ s ， t′ s ]Îe.mo do 4: Starting from i， find the first index j of a.mos.t. [t js ， t je ] Î a. mo and t je < t′ s and t (j+1)e > t′ s 5: Append [t js ， t′ s ] to concat(a，e).mo 6: Let I = j 7: Return concat(a，e).mo Table 1 Two cases of episode growt a.mano e.mano b.mano {[1，2]， [9，12] } {[3，3]， [7，7]， [11，11]} {[1，3]} {[2，5]， [9，12]} {[3，3]， [7，7]， [11，11]} {[2，7]} 表1. 情节增长的两种情形 SubProcedure Compute MANO(b) Input: b: an episode with its mo Output: b. mano: the earliest mano of episode b 1: Let b. mano = {1} 2: Let i = 1 3: Let j = i + 1 4: While j < |b. mo| do 5: Find the first index k of b.mo after js.t. [t is ， t ie ] Î b. mo and [t ks ， t ke ] Î b. mo and t ie < t ks 6: b.mano=b. mano ∪ {k} 7: Let i = k 8: Let j = i + 1 9: Return b.mano 3.4. 算法MANEPI运行实例 设事件流S = <(A，1)， (A，2)， (B，3)， (D，4)， (A，5)， (C，6)， (B，7)， (E，8)， (A，9) (C，10)， (B，11)， (A，12)， (C，13)>以及min_sup = 2。首先，MANEPI通过单遍扫描S，得到所有的频繁1-情节< A >、< B >和< C >，并在SPT中生成根结点的孩子结点N < A > 、N < B > 和N < C > ；然后进行第一次情节增长，将已发现的频繁情节< A >与频繁1-情节< A >串接后形成新情节< AA >，通过调用ComputeMO和ComputeMANO得到< AA >.sup = |{[1， 2]， [5， 9]}| = 2 ≥ min_sup，在SPT中生成结点N < A > 的孩子结点N < AA > ；接着，进行第二次情节增长，将已发现的频繁情节< AA >与频繁1-情节< A >串接后形成新情节< AAA >，得< AAA >.sup = |{[1， 5]}| = 1 < min_sup，因此，无须以< AAA >为前缀进行情节增长，算法返回至上一层，将已发现的频繁情节< AA >与频繁1-情节< B >串接后形成新情节 ，∙∙∙；；最后，在S上发现了如 表2所示的18个频繁情节，挖掘过程中产生的共享前缀树如  图1所示。 3.5. 算法MANEPI正确性证明 引理2. 给定最小发生集的情节a和e，过程ComputeMO能够正确计算新情节concat(a，e)的最小发生集。 证明：对于e.mo中的每一个发生 [ t ′ s ， t ′ s ] (第3行)，ComputeMO通过单遍扫描e.mo查找一个最大的j(第4行)满足[t js ， t je ] Î a.mo且 t j e < t ′ s 且 t ( j + 1 ) e > t ′ s ，若不存在这样的j，则停止扫描e.mo。因 [ t j s ， t j e ] 是a出现在e的发生 [ t ′ s ， t ′ s ] 之前的最后一次发生，故 [ t j s ， t ′ s ] 是concat(a，e)的一次最小发生，concat(a，e).mo是concat(a，e)的所有最小发生组成的集合。引理2证毕。■ 引理3. 给定最小发生集的情节b，过程ComputeMANO能够正确计算b最早出现的所有最小且非重叠发生组成的最大集合。 证明： 图1. S上的频繁情节共享前缀树 Table 2 All frequent episodes with number episode mo mano 1 {[1，1]， [2，2]， [5，5]， [9，9]， [12，12]} {1，2，3，4，5} 2 {[3，3]， [7，7]， [11，11]} {1，2，3} 3 {[6，6]， [10，10]， [13，13]} {1，2，3} 4 {[1，2]， [2，5]， [5，9]， [9，12]} {1，3} 5 {[1，3]， [2，7]， [5，11]} {1，3} 6 {[2，6]， [5，10]， [9，13]} {1，3} 7 {[2，3]， [5，7]， [9，11]} {1，2，3} 8 {[2，5]， [5，9]， [9，12]} {1，3} 9 {[2，6]， [5，10]， [9，13]} {1，3} 10 {[2，6]， [5，10]， [9，13]} {1，3} 11 {[5，6]， [9，10]， [12，13]} {1，2，3} 12 {[5，7]， [9，11]} {1，2} 13 {[3，5]， [7，9]， [11，12]} {1，2，3} 14 {[3，6]， [7，10]， [11，13]} {1，2，3} 15 {[3，6]， [7，10]， [11，13]} {1，2，3} 16 {[6，9]， [10，12]} {1，2} 17 {[6，7]， [10，11]} {1，2} 18 {[6，9]， [10，12]} {1，2} 表2. S上的频繁情节 1) 过程ComputeMANO首先将b.mo中第一个发生[t 1s ， t 1e ]的索引号i(i = 1)添加至b.mano中(第1行)，然后从索引号j = i + 1开始(第4行)单遍扫描b.mo，以查找最小的k(第5行)满足[t is ， t ie ] Î b.mo且t ie < t ks ，即查找b的第一个与[t is ， t ie ]非重叠的发生[t ks ， t ke ]，若不存在这样的k，则停止扫描b.mo。由于每次添加至b.mano中的发生(第6行)均与当前b.mano中的最后一次发生非重叠，所以最终的b.mano应是b最早出现的所有非重叠发生组成的集合。 2) 由引理2知，b.mano是b的最小发生集。 综合1)和2)，引理3证毕。■ 引理4：对于已发现的频繁情节a，过程MineGrow能够正确发现所有以a为前缀的频繁情节，并在SPT中生成相应的结点。 证明对于频繁情节a，过程MineGrow根据引理2和引理3，进行以a为前缀的一次情节增长(第2-4行)，若concat(a，e)是非频繁的，则不在SPT中生成相应的结点，根据定理1，concat(a，e)的所有超情节也是非频繁的，过程MineGrow将以a为前缀进行下一次情节增长(第1行)；若concat(a，e)是频繁的，则在SPT中生成相应的结点(第6行)，并以concat(a，e)为前缀进行一次情节增长(第7行)，如此迭代结束后，能够发现所有以a为前缀的频繁情节，并在SPT中生成相应的结点。引理4证毕。■ 引理5：给定事件流S和支持度阈值min_sup，算法MANEPI能够正确发现S上的所有频繁情节，并在SPT中生成相应结点。 证明MANEPI首先单遍扫描S发现所有频繁1-情节(第1行)，然后对每个频繁1-情节进行如下处理：在SPT中生成相应结点，并以该情节为前缀进行情节增长(第2~6行)。由引理4知，MANEPI最终能够发现所有频繁情节，并在SPT中生成相应结点。引理2.5得证。■ 3.6. 算法MANEPI复杂度分析 设S为L个事件组成的事件流，e为S上的事件类型集，FE为S上的所有频繁情节组成的集合，sup_max为所有频繁1-情节的最大支持度，则算法MANEPI的复杂度分析如下： 定理2：MANEPI的时间复杂度为O(|FE| · |e| · L)。 证明：对于FE中的每个频繁情节a和e中的每个频繁1-情节e，旨在找到最早出现的concat(a，e).mano的情节增长操作是MANEPI的主要时间代价。完成一次情节增长只需单遍扫描a.mo和e.mo，其时间复杂度为O(L)。由定理1可知，MANEPI只需以FE中的每个情节为前缀进行情节增长，增长的次数为频繁1-情节的个数，其上界为|e|，因此，算法MANEPI完成全部的情节增长操作所需的时间复杂度为O(|FE| ∙ |e| · L)。定理2证毕。■ 定理3：MANEPI的空间复杂度为O(sup_max · |FE|)。 证明算法MANEPI共发现了|FE|个频繁情节，而每个频繁情节至多有sup_max个最小且非重叠的发生，故算法所需的空间复杂度为O(sup_max · |FE|)。定理3证毕。■