自然语言处理hanlp------8AC自动机

本文涉及的产品
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_基础版,每接口每天50万次
NLP自然语言处理_高级版,每接口累计50万次
简介: 自然语言处理hanlp------8AC自动机

前言

DAT每次转移的时间复杂度都是常数,全切分长度为n的文本时,时间复杂度是0(n2 ^22


例子:

假设词典收录了所以的阿拉伯数字,那么对文本“123”进行扫描,发生了6次的状态转移

1、12、123;2、23;3

推广一下:“123···n”扫描就发生了n+(n-1)+(n-2)+···+1=2(n+1)n
=0(n2 ^22次状态转移


但是,我们学习自然语言处理就为了更快,更牛逼!

AC自动机就是一种可以一次扫描查询出所有出现的单词的复杂度为0(n)的多模式匹配算法。

简单说一下AC自动机的AC,就是这俩人,贝尔实验室的Aho和Corasick。


提示:以下是本篇文章正文内容,下面案例可供参考


一、从字典树到AC自动机

前面说了例子,就是为了让一次扫描查询所有出现过的单词。我们过渡到了AC自动机。字典树是前缀树,AC自动机是在前缀树的基础上,为前缀树上的每个节点建立一颗后缀树。节省大量的查询时间。

AC自动机goto表fail表output表组成。


1. goto表

goto表也称作success表,如下举例理解:


使用ushers为母文本,模式串集合为{he,she,his,hers}

此时的goto表为

20210201142235241.png

它的构建和前缀树一致,唯一不同的地方是:根节点不光可以按照h和s转移,还接受其他任意字符,转移终点都是自己。这样形成了一个圈,圈的目的在于扫描时若遇到非h且非s的字符,状态机一直保持初始状态。


2.output表

这个很简单,写出对应的状态编号的输出值的表就行了

20210201182135617.png


将其与goto表结合如下

2021020118241738.png

output 表中的元素有两种,一种是从初始状态到当前状态的路径本身对应的模式串(比如2号状态),另一种是路径的后缀所对应的模式串(比如5号状态)。于是它的构造也分为两步,第一步与字典树类似,就是记录完整路径对应的模式串。第二步则是找出所有路径后缀及其模式串,这一步可以与fail表的构造同步进行。


3.fail表

fail表中保存了失配时的fail指针,fail指针就是当前位置失配以后能够跳转继续进行匹配的字符位置,达到匹配过程中不需要回溯的效果。构建过程使用了BFS(宽度优先搜索)算法。


晗佬的解释是:fail表保存的是状态间一对一的关系,存储状态转移失败后应当回到的最佳状态。最佳状态指的是能记住已匹配上的字符串的最长后缀的那个状态


仍然从实例来理解fail表如何创建


(1)初始状态的goto表是满的,永远不会失败,因此没有fail指针。与初始状态直接相连的所有状态,其fail指针都指向初始状态,如图2-11中的虚线所示。

20210201183928206.png

(2)从初始状态开始进行广度优先遍历(BFS),若当前状态S接受子符c直达的状态为T,则沿着S的fail指针回溯,直到找到第一个前驱状态F,使得 F.goto( c ) != null。将T的fail指针设为F.goto( c ),也即:

F = S.fail
while F.goto( c ) == null
    F = F.fail
T.fail = F.goto( c )


(3)由于F路径是T路径的后缀,也就是说T一定包含F,因而T的 output也应包含F的output。于是更新:

T.output += F.output


完善后得出:(反复多对照图和上述流程理解就可)

20210201191351440.png


从后往前看,便是后缀树,举例一个如下:

20210201191902761.png

字典树状态转移可能失败,失败时扫描起点往右挪―下,重新扫描。而在AC自动机中,按goto表转移失败时就按fail表转移永远不会失败,因此只需扫描一遍文本。


二、代码实现(看看即可)

自动机状态部分代码

image.png


fail表建立部分代码:

image.png


演示上述经典案例ushers

20210201193852823.png


三、速度测评

仍然是直接上晗佬的测评结果

image.png

可以看出,已经比BinTrie快了一点了,但比前面所需的DAT双数组字典树,还是逊色了一些,这里,我们就可以考虑,如果将双数组与AC自动机结合会怎么样呢??也就是下节的内容了。


总结

晗佬的书循序渐进,亲情推荐大家买来阅读,一步一步,相信我们都可以真正的去入门自然语言处理!



相关文章
|
Java Linux
使用supervisor纳管java进程,自动重启服务
使用supervisor守护java进程,实现服务智能管理,自动重启。
1979 0
|
6月前
|
编解码 UED 开发者
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发之常见布局
本文主要介绍了自适应布局与响应式布局的相关内容。自适应布局部分涵盖线性布局、层叠布局、弹性布局和网格布局,详细说明了各布局的特性及使用方法,例如线性布局中的排列、拉伸与缩放,弹性布局的方向、换行与对齐方式等。响应式布局则重点讲解了栅格系统和媒体查询,阐述如何通过栅格组件和媒体查询条件实现不同设备上的适配效果。这些技术帮助开发者灵活应对多尺寸屏幕的设计需求,提升用户体验。
342 55
|
缓存 前端开发 安全
数据同步原理
数据同步原理
323 10
数据同步原理
|
11月前
|
存储 缓存 数据挖掘
StarRocks 原理详解:探索高效 OLAP 的奥秘
StarRocks 是一款高性能分析型数据仓库,采用向量化、MPP架构、CBO等技术,实现多维、实时、高并发的数据分析。它支持从各类数据源高效导入数据,兼容MySQL协议,并具备水平扩展、高可用等特性,广泛应用于实时数仓、OLAP报表等场景。StarRocks 解决了传统数仓在查询性能、数据导入、扩展性和灵活性等方面的挑战,助力企业实现数据驱动的决策。其分布式架构和智能物化视图等功能显著提升了查询效率,适用于大数据生态中的各种复杂需求。
1848 15
|
数据采集 存储 监控
Java爬虫:数据采集的强大工具
在数据驱动的时代,Java爬虫技术凭借其强大的功能和灵活性,成为企业获取市场信息、用户行为及竞争情报的关键工具。本文详细介绍了Java爬虫的工作原理、应用场景、构建方法及其重要性,强调了在合法合规的前提下,如何有效利用Java爬虫技术为企业决策提供支持。
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
223 0
|
安全 关系型数据库 MySQL
Mysql 8.0 安装和使用遇到的各种问题(持续更新)
MySQL 8.0 安装到 服务器时,遇到的一些问题;安装、远程访问、密码编码格式不对、大小写区分、密码重置、修改密码 等操作
成功解决:java: 无效的目标发行版: 17
这篇文章讲述了如何解决在启动SpringBoot项目时遇到的"无效的目标发行版: 17"的问题,主要是通过修改IDEA内置的编译设置,确保它使用正确的JDK版本。
【qt】自定义对话框(1)
【qt】自定义对话框(1)
138 0
|
SQL 分布式计算 Java
IDEA 打包 Spark 项目 POM 文件依赖
这是一个 Maven POM 示例,用于构建一个使用 Spark 与 Hive 的项目,目标是将数据从 Hive 导入 ClickHouse。POM 文件设置了 Scala 和 Spark 的依赖,包括 `spark-core_2.12`, `spark-sql_2.12`, 和 `spark-hive_2.12`。`maven-assembly-plugin` 插件用于打包,生成包含依赖的和不含依赖的两种 JAR 包。`scope` 说明了依赖的使用范围,如 `compile`(默认),`provided`,`runtime`,`test` 和 `system`。
397 0