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


前言

DAT每次转移的时间复杂度都是常数,全切分长度为n的文本时,时间复杂度是0(n 2 ^2 2
例子:
假设词典收录了所以的阿拉伯数字,那么对文本“123”进行扫描,发生了6次的状态转移
1、12、123;2、23;3
推广一下:“123···n”扫描就发生了n+(n-1)+(n-2)+···+1= ( n + 1 ) n 2 \frac{(n+1)n}{2} 2(n+1)n=0(n 2 ^2 2)次状态转移。

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

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

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

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

一、从字典树到AC自动机

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

1. goto表

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

使用ushers为母文本,模式串集合为{he,she,his,hers}
此时的goto表为
在这里插入图片描述
它的构建和前缀树一致,唯一不同的地方是:根节点不光可以按照h和s转移,还接受其他任意字符,转移终点都是自己。这样形成了一个圈,圈的目的在于扫描时若遇到非h且非s的字符,状态机一直保持初始状态。

2.output表

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

在这里插入图片描述
将其与goto表结合如下

在这里插入图片描述

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

3.fail表

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

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

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

(1)初始状态的goto表是满的,永远不会失败,因此没有fail指针。与初始状态直接相连的所有状态,其fail指针都指向初始状态,如图2-11中的虚线所示。
在这里插入图片描述
(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

完善后得出:(反复多对照图和上述流程理解就可)
在这里插入图片描述

从后往前看,便是后缀树,举例一个如下:
在这里插入图片描述
字典树状态转移可能失败,失败时扫描起点往右挪―下,重新扫描。而在AC自动机中,按goto表转移失败时就按fail表转移永远不会失败,因此只需扫描一遍文本。

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

自动机状态部分代码
在这里插入图片描述
fail表建立部分代码:

在这里插入图片描述
演示上述经典案例ushers

在这里插入图片描述

三、速度测评

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

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


总结

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

此外:本人创建了QQ交流群,希望大家来交流学习(新群人少,不是假群o(╥﹏╥)o…)
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iterhui

谢谢您对iterhui的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值