序列模式及PrefixSpan算法

1.序列模式介绍
2.Prefixspan算法基础
3.Prefixspan算法原理
4.Prefixspan算法举例

1.序列模式介绍

什么是序列模式?
序列模式挖掘(sequence pattern mining)是数据挖掘的内容之一,指挖掘相对时间或其他模式出现频率高的模式。

基础概念介绍:
1.序列是如何产生的:
例如,一个事务数据库,一个事务代表一笔交易,一个单项代表交易的商品,单项属性中的数字记录的是商品ID

一般为了方便处理,需要把数据库转化为序列数据库。方法是把用户ID相同的记录合并,有时每个事务的发生时间可以忽略,仅保持事务间的偏序关系。

序列简介:
序列(Sequence)通常以SID表示,一个序列即是一个完整的信息流。每个序列由不同的元素按顺序有序排列,每个元素由不同项目(或者也可以称之为事件)组成。
例如一条序列<(10,20)30(40,60,70)>有3个元素,分别是(10,20),30,(40,60,70);3个事务的发生时间是由前到后。其中项目10和项目20是同时发生的,所以处在同一个元素中。这条序列是一个6-序列。

子序列简介
对于序列t和s,如果t中每个有序元素都是s中的一个有序元素的子集,那么t是s的子序列。形式化为,序列 t=<t1,t2,⋯,tm> 和 s=<s1,s2,⋯,sn>,如果 1≤j1≤j2≤⋯≤jm≤n,使得 t1⊆sj1,t2⊆sj2,⋯,tm⊆sjm,则t是s的子序列,并且t包含在s中。
例如:

支持度简介
序列αα在序列数据库S中的支持度为序列数据库S中包含序列支持度的序列个数,记为Support(αα)。给定最小支持度阈值ξξ,如果序列αα在序列数据库中的支持数不低于ξξ,则称序列αα为频繁序列。长度为l的序列模式记为l-模式。
序列模式挖掘:找出所有的频繁子序列,即该子序列在序列集中的出现频率不低于最小支持度阈值。例子:设序列数据库如下图所示,并设用户指定的最小支持度min-support = 2。

2.Prefixspan算法基础

PrefixSpan算法的全称是Prefix-Projected Pattern Growth,即前缀投影的模式挖掘。
基本概念简介:
前缀prefix:

对于序列A={a1,a2,…an}和序列B={b1,b2,…bm},n≤m,满足a1=b1,a2=b2…an−1=bn−1,而an⊆bn,则称A是B的前缀。
比如对于序列数据B=<a(abc)(ac)d(cf)>,则A=<a(abc)a>是B的前缀。当然B的前缀不止一个,比如<a>, <aa>, <a(ab)> 也都是B的前缀。

后缀(前缀投影):
前缀投影,其实前缀投影这儿就是我们的后缀,有前缀就有后缀嘛。前缀加上后缀就可以构成一个我们的序列。下面给出前缀和后缀的例子。对于某一个前缀,序列里前缀后面剩下的子序列即为我们的后缀。如果前缀最后的项是项集的一部分,则用一个“_”来占位表示。
下面这个例子展示了序列<a(abc)(ac)d(cf)>的一些前缀和后缀,要注意的是,如果前缀的末尾不是一个完全的项集,则需要加一个占位符。

在PrefixSpan算法中,相同前缀对应的所有后缀的结合我们称为前缀对应的投影数据库。

3.PrefixSpan算法原理

从长度为1的前缀开始挖掘序列模式,搜索对应的投影数据库得到长度为1的前缀对应的频繁序列,然后递归的挖掘长度为2的前缀所对应的频繁序列,以此类推,一直递归到不能挖掘到更长的前缀挖掘为止。
输入:序列数据集S和支持度阈值α
    输出:所有满足支持度要求的频繁序列集
    1)找出所有长度为1的前缀和对应的投影数据库
    2)对长度为1的前缀进行计数,将支持度低于阈值α的前缀对应的项从数据集S删除,同时得到所有的频繁1项序列,i=1.
    3)对于每个长度为i满足支持度要求的前缀进行递归挖掘:
      a) 找出前缀所对应的投影数据库。如果投影数据库为空,则递归返回。
      b) 统计对应投影数据库中各项的支持度计数。如果所有项的支持度计数都低于阈值α,则递归返回。
      c) 将满足支持度计数的各个单项和当前的前缀进行合并,得到若干新的前缀。
      d) 令i=i+1,前缀为合并单项后的各个前缀,分别递归执行第3步。

4.PrefixSpan算法举例实现


里面长度为1的前缀包括<a>, <b>, <c>, <d>, <e>, <f>,<g>我们需要对这6个前缀分别递归搜索找各个前缀对应的频繁序列。如下图所示,每个前缀对应的后缀也标出来了。由于g只在序列4出现,支持度计数只有1,因此无法继续挖掘。我们的长度为1的频繁序列为<a>, <b>, <c>, <d>, <e>,<f>。去除所有序列中的g,即第4条记录变成<e(af)cbc>。

现在我们开始挖掘频繁序列,分别从长度为1的前缀开始。这里我们以d为例子来递归挖掘,其他的节点递归挖掘方法和d一样。

1.首先我们通过前缀d在所有序列中找到其前缀投影(后缀)的结果有:
<(cf)>
<c(bc)(ae)>
<(_f)cb>
对d所有出现的后缀进行计数,得到{a:1, b:2, c:3, d:0, e:1, f:1,_f:1}。
(注意f和_f是不一样的,前者是在和前缀d不同的项集,而后者是和前缀d同项集<(df)>)
得到>=2频繁序列为和
对应后缀有<_c(ae)>,对其计数{a:1, _c:1, e:1}
支持度全部不达标所以此项挖掘结束。 然后返回来对项计数:

2. 写出以为前缀的投影序列有<_f>, <(bc)(ae)>,
然后我们对的后缀进行支持度计数→ {b:2, a:1, c:1, e:1, _f:1}
只有b满足支持度阈值
因此我们得到前缀为dc的三项频繁序列为。我们继续递归以为前缀的频繁序列
对应后缀支持度全部不达标此项挖掘结束,结果如下。
pattern:[[‘d’]], support:3pattern:[[‘d’], [‘b’]], support:2pattern:[[‘d’], [‘c’]], support:3pattern:[[‘d’], [‘c’], [‘b’]], support:2

附上python3.6的代码:

import sys
PLACE_HOLDER = '_'def read(filename):S = []with open(filename, 'r') as input:for line in input.readlines():elements = line.split(',')      #分隔符s = []for e in elements:s.append(e.split())S.append(s)return Sclass SquencePattern:def __init__(self, squence, support):self.squence = []for s in squence:self.squence.append(list(s))  #元组换成列表self.support = supportdef append(self, p):                           #如果第一位是‘_’则remove后再加到squence里面if p.squence[0][0] == PLACE_HOLDER:first_e = p.squence[0]first_e.remove(PLACE_HOLDER)self.squence[-1].extend(first_e)self.squence.extend(p.squence[1:])else:self.squence.extend(p.squence)self.support = min(self.support, p.support)def prefixSpan(pattern, S, threshold):patterns = []f_list = frequent_items(S, pattern, threshold)for i in f_list:p = SquencePattern(pattern.squence, pattern.support)p.append(i)patterns.append(p)p_S = build_projected_database(S, p)p_patterns = prefixSpan(p, p_S, threshold)patterns.extend(p_patterns)return patternsdef frequent_items(S, pattern, threshold):items = {}_items = {}f_list = []if S is None or len(S) == 0:return []if len(pattern.squence) != 0:last_e = pattern.squence[-1]else:last_e = []for s in S:# class 1print(s)is_prefix = Truefor item in last_e:if item not in s[0]:is_prefix = Falsebreak# print(is_prefix)if is_prefix and len(last_e) > 0:index = s[0].index(last_e[-1])if index < len(s[0]) - 1:for item in s[0][index + 1:]:if item in _items:print(s)_items[item] += 1else:_items[item] = 1# class 2if PLACE_HOLDER in s[0]:for item in s[0][1:]:if item in _items:_items[item] += 1else:_items[item] = 1s = s[1:]# class 3counted = []for element in s:for item in element:if item not in counted:counted.append(item)if item in items:items[item] += 1else:items[item] = 1f_list.extend([SquencePattern([[PLACE_HOLDER, k]], v) for k, v in _items.items() if v >= threshold])f_list.extend([SquencePattern([[k]], v) for k, v in items.items() if v >= threshold])sorted_list = sorted(f_list, key=lambda p: p.support)   #lambda是虚拟函数return sorted_listdef build_projected_database(S, pattern):"""suppose S is projected database base on pattern's prefix,  pattern是当前的前缀,S为其投影数据库so we only need to use the last element in pattern tobuild projected database"""# print(S)# print(pattern.squence)p_S = []last_e = pattern.squence[-1]last_item = last_e[-1]for s in S:p_s = []for element in s:is_prefix = Falseif PLACE_HOLDER in element:if last_item in element and len(pattern.squence[-1]) > 1:is_prefix = Trueelse:is_prefix = Truefor item in last_e:if item not in element:is_prefix = Falsebreakif is_prefix:e_index = s.index(element)i_index = element.index(last_item)if i_index == len(element) - 1:p_s = s[e_index + 1:]else:p_s = s[e_index:]# index = element.index(last_item)e = element[i_index:]e[0] = PLACE_HOLDERp_s[0] = ebreakif len(p_s) != 0:p_S.append(p_s)return p_Sdef print_patterns(patterns):for p in patterns:print("pattern:{0}, support:{1}".format(p.squence, p.support))if __name__ == "__main__":S = read("PrefixSpan_test.txt")# frequent_items(S, SquencePattern(['b'],2), 2)patterns = prefixSpan(SquencePattern([], sys.maxsize), S, 2)print_patterns(patterns)

PrefixSpan算法详解+举例实现+代码相关推荐

  1. 相位 unwrap 与 wrap 算法详解(附代码)

    相位 unwrap 与 wrap 算法详解(附代码) 最近接手了一个项目,光通信方面的,我负责编写初测结果的数据处理算法,其中有一个算法叫做 unwrap 与 wrap,之前没有听说过.通过询问同事与 ...

  2. kmeans算法详解和python代码实现

    kmeans算法详解和python代码实现 kmeans算法 无监督学习和监督学习 监督学习: 是通过已知类别的样本分类器的参数,来达到所要求性能的过程 简单来说,就是让计算机去学习我们已经创建好了的 ...

  3. 二分查找算法详解(附代码)

    二分查找算法详解(附代码) 注: 现有一个升序 不重复的数组 查询target是否在此数组中并返回序号 使用条件 使用二分算法的两个条件: 有序 不重复 混淆处 二分算法两种方式容易弄混淆的地方:就是 ...

  4. AC自动机算法详解以及Java代码实现

    详细介绍了AC自动机算法详解以及Java代码实现. 文章目录 1 概念和原理 2 节点定义 3 构建Trie前缀树 3.1 案例演示 4 构建fail失配指针 4.1 案例演示 5 匹配文本 5.1 ...

  5. 编辑距离算法详解和python代码

    编辑距离(Levenshtein Distance)算法详解和python代码 最近做NLP用到了编辑距离,网上学习了很多,看到很多博客写的有问题,这里做一个编辑距离的算法介绍,步骤和多种python ...

  6. 基于多相滤波器的数字信道化算法详解(Python, Verilog代码已开源)

    基于多相滤波器的数字信道化算法详解 推导过程 总结 仿真 本文详细介绍了基于多相滤波器的数字信道化算法的推导过程, 如果您在阅读的过程中发现算法推导过程中有任何错误, 请不吝指出. 此外, 进入我的G ...

  7. 敏感词或关键词过滤,DFA算法详解及python代码实现

    一.前言 近期项目有了一个过滤敏感词的功能需求,在网上找了一些方法及解说,发现DFA算法比较好用,容易实现,但很多文章解释得不太清楚,这里将其详细描述,并用python代码实现. 二.DFA算法详解 ...

  8. paxos算法详解以及模拟代码

    0 paxos算法解决了什么问题 现在有n个人组成提一个会议,这个会议的目的是为了确定今年的税率,那么每个人都会提出自己认为的今年的合理的税率,为了大家能够达成一致,有了paxos算法.实际里,这个会 ...

  9. K-means算法详解及python代码实现

    K-means算法 算法步骤 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python)(待更.......) 算法步骤 1.随机选取K个点作为初始聚类中心 2.计算各个数据到个聚类中心的 ...

最新文章

  1. 计算机性能指标ppt,计算机网络分类与主要性能指标.ppt
  2. 拿haojava官方过程
  3. Java和C/C++程序实时通讯数据移植问题的研究
  4. UIImage 压缩
  5. 【Java】冒泡排序
  6. 【资源下载】 UC 伯克利 Chelsea Finn 博士论文(新起之秀——MAML)《Learning to Learn with Gradients》下载--2018ACM最佳博士论文下载
  7. ubuntu系统重启后桌面分辨率减小的原因及解决方法
  8. AcWing 1270. 数列区间最大值(RMQ问题)
  9. html二维数组查找车票,火车票售票系统
  10. 十七款PDF在线处理转换器,目前最全合集
  11. 2022年网络规划设计师最新考纲变化
  12. Android编程怎么打开,安卓手机如何开启开发者模式?简单三步骤教你解决!
  13. 整理一下vue 移动端模板框架搭建
  14. ajax jsonp跨域访问,jquery ajax怎么使用jsonp跨域访问
  15. 文件下载中使用inputStream流获取文件大小
  16. Unity3D中的动态字体和静态字体
  17. 学术-数学:费马猜想
  18. 信息系统风险评估内容
  19. PHP之 微信支付 查询企业付款银行卡API 或 查询给企业付款是否到账 功能业务处理
  20. 某软件测试大纲,软件测试(验收)大纲

热门文章

  1. HTML霓虹灯闪光效果,带鼠标滑过特效的jQuery霓虹灯文字插件
  2. 在知识蒸馏中不要忘记教师网络detach()
  3. 调查数据分析的基本问题
  4. 西游记中孙悟空为什么总是欺负捉弄嘲笑猪八戒?
  5. 【第74期】想做游戏策划,得有点屁股精神
  6. 三年级计算机秒打汉字教案,武汉社版三年级全册信息技术 18.汉字输入我能行 教案...
  7. MySQL Sharding详解
  8. Java实现获取某年某月第一天最后一天
  9. 自动化软件测试 - 通过 Android Studio 开发 App 自动拦截读取短信验证码
  10. 一张图表看懂如何选购投影幕布