自然语言处理学习笔记(七)————字典树效率改进
目录
1. 首字散列其余二分的字典树
2.双数组字典树
3.AC自动机(多模式匹配)
(1)goto表
(2)output表
(3)fail表
4.基于双数组字典树的AC自动机
字典树的数据结构在以上的切分算法中已经很快了,但还有一些基于字典树的算法改进,把分词速度推向了千万字每秒的级别,主要按照以下递进关系优化:
- 首字散列其余二分的字典树
- 双数组字典树
- AC自动机(多模式匹配)
- 基于双数组字典树的AC自动机
1. 首字散列其余二分的字典树
散列函数用来将对象转换为整数。散列函数必须满足的基本要求是:对象相同,散列值必须相同。散列函数设计不当,则散列表的内存效率和查找效率都不高。Python没有char类型,字符被视作长度为1的字符串,所以实际调用的就是str的散列函数。在64位系统上,str的散列函数返回64位的整数。但Unicode字符总共也才136690个,远远小于2^64。这导致两个字符在字符集中明明相邻,然而散列值却相差万里。
Java中的字符散列函数则要友好一些,Java中字符的编码为UTF-16。每个字符都可以映射为16位不重复的连续整数,恰好是完美散列。这个完美的散列函数输出的是区间[0,65535]内的正整数,用来索引子节点非常合适。具体做法是创建一个长为65536的数组,将子节点按对应的字符整型值作为下标放入该数组中即可。这样每次状态转移时,只需访问对应下标就行了,这在任何编程语言中都是极快的。然而这种待遇无法让每个节点都享受,如果词典中的词语最长为l,则最坏情况下字典树第l层的数组容量之和为O(65536^l)。内存指数膨胀,不现实。一个变通的方法是仅在根节点实施散列策略。
字典树其实就是一棵前缀树(指的是前缀相同的词语必然经过同一个节点) 如何加速呢?在扫描"自然语言处理"这句话的时候,朴素实现会依次查询"自"、"自然"、"自然语"、"自然语言"等词语是否在词典中。但事实上,如果"自然"这条路径不存在于前缀树中,则可以断定一切以"自然"开头的词语都不可能存在。
2.双数组字典树
状态转移复杂度为常数的数据结构。它由base和check两个数组构成,又简称双数组
3.AC自动机(多模式匹配)
我们已经知道,字典树的本质就是DFA,假设每次状态转移的时间复杂度为常数。那么对文本“123”的扫描一共发生了六次状态转移:1、12、123;2、23;3.对于文本长度为n来说,共发生了 O(n^2) 次状态转移,所以复杂度为 O(n^2)
那么可不可以只进行一次扫描就查询出所有出现的单词呢,AC自动机就可以做到,它是一种 O(n) 复杂度的算法。给定多个词语(模式串, pattern),从母文本中匹配他们的问题称为多模式匹配。在中文处理中,汉字就是常见的短模式串,AC自动机在中文自然语言处理中应用更广泛。
举个例子:我们的模式串为“自然语言”,如果用字典树查询,以“自“为起点, 找到”自然语言“后,起点又退回到”然“继续扫描...如果扫描到”自然语言“的同时知道”然语言“、”语言“、”言”不在字典树中,则可以少查询三次,观察这三个字符串,它们共享递进式的后缀,所以可以引入后缀树。AC自动机在前缀树的基础上为每个节点建立后缀树,节省大量查询。
AC自动机由goto表,fail表和output表组成,分别类似于前缀树和后缀树。
(1)goto表
goto表也叫success表,其实就是一颗前缀树,用来将每个模式串索引到前缀树上。下面引用经典的ushers作为母文本,模式串集合为{he,she,his,hers}
它的构建与前缀树一致,唯一不同的是,根节点不光可以按h和s转移,还接受任意其他字符,转移终点都是自己。这样形成了一个圈,使得一棵树变为一幅有向有环图。这个圈的目的在于,扫描时若遇到非h且非s的字符,状态机一直保持初始状态。
(2)output表
给定一个状态,我们需要知道该状态是否对应某个或某些模式串,以决定是否输出模式串以及对应的值。这时用到的关联结构被称为utput 表。在图2-9所示的例子中,output表中的状态就是图中的深蓝色节点,对应的output 如表所示。
output 表中的元素有两种,一种是从初始状态到当前状态的路径本身对应的模式串(比如2号状态),另一种是路径的后缀所对应的模式串(比如5号状态)。于是它的构造也分为两步,第一步与字典树类似,就是记录完整路径对应的模式串。第二步则是找出所有路径后缀及其模式串,这一步可以与fai1表的构造同步进行。
为goto表加上output表
(3)fail表
fail表保存的是状态间一对一的关系,存储状态转移失败后应当回退的最佳状态。最佳状态指的是能记住已匹配上的字符串的最长后缀的那个状态。比如,匹配she后来到状态5,再来一个字符,goto失败,哪个状态才是fail的最佳选择呢?当前匹配到的字符串为she,最长后缀为he,对应路径0-1-2。因此,状态2就是状态5 fail的最佳选择。fail到状态2之后,自动机记住了he,做好了接受r的准备。再比如,匹配his后来到状态7,再来一个字符,goto失败了。his 的最长后缀为is,可惜没有这条路径;次长后缀为s,对应路径0-3,因此状态7应当fail到3。
如何构建fail表?定义s为当前状态;S.goto(c)为转移表,返回s按字符c转移后的状态,null表示转移失败;S.fail为fail表,代表转移失败时从状态S回退的状态。fail表的构建方法如下。
(1)初始状态的goto表是满的,永远不会失败,因此没有fail指针。与初始状态直接相连的所有状态,其fail指针都指向初始状态,如图中的虚线所示。
(2)从初始状态开始进行广度优先遍历(BFS),若当前状态S接受字符c直达的状态为T,则沿着S的fail指针回溯,直到找到第一个前驱状态F,使得F.goto(c) != null。将T的fail指针设F.goto(c),也即:
F = S.fail
while F.goto(c) == nullF= F.fail
T.fail = F.goto(c)
(3)由于F路径是T路径的后缀,也就是说T一定包含F,因而T的output 也应包含F的output。于是更新:
T.output += F.output
为上图加上完整的fail表后,自动机如图所示。
算上fail表的虚线,从后往前看,AC自动机由许多后缀树构成。其中一棵如图所示。
字典树状态转移可能失败,失败时扫描起点往右挪一下,重新扫描。而在AC自动机中,按goto表转移失败时就按fail转移,永远不会失败,因此只需扫描一遍文本。
4.基于双数组字典树的AC自动机
双数组字典树能在O(1)(1是模式串长度)时间内高速完成单串匹配,并且内存消耗可控,然而软肋在于多模式匹配。如果要匹配多个模式串,必须先实现前缀查询,然后频繁截取文本后缀才可多匹配。比如 ushers、shers、hers…这样一份文本要回退扫描多遍,性能较低。既然 AC 自动机的goto表本身就是一棵字典树,能否利用双数组字典树来实现它呢?如果能用双数组字典树表达 AC自动机,就能集合两者的优点,得到一种近乎完美的数据结构。
ACDAT的基本原理是替换 AC自动机的goto表,也可看作为一棵双数组字典树的每个状态(下标)附上额外的信息。上节提到,AC自动机的goto表就是字典树,只不过AC自动机比字典树多了output 表和fail表。那么ACDAT的构建原理就是为每个状态(base[i]和check[i])构建output[i][]和fail[i]。具体说来,分为3步。
(1)构建一棵普通的字典树,让终止节点记住对应模式串的字典序。
(2)构建双数组字典树,在将每个状态映射到双数组时,让它记住自己在双数组中的下标。
(3)构建AC自动机,此时fail表中存储的就是状态的下标。
相关文章:
自然语言处理学习笔记(七)————字典树效率改进
目录 1. 首字散列其余二分的字典树 2.双数组字典树 3.AC自动机(多模式匹配) (1)goto表 (2)output表 (3)fail表 4.基于双数组字典树的AC自动机 字典树的数据结构在以上的切分算法中已经很快了&#x…...
forEach和map有什么区别,使用场景?
forEach和map有什么区别,使用场景? 区别什么意思?forEach: 不直接改变原始数组,但可以在回调中更改原始数组。 区别 forEach 和 map 都是数组的常用方法,但它们有不同的目的和用法。下面是它们之间的主要区别以及各自…...
【Spring Boot】SpringBoot完整实现社交网站系统
一个完整的社交网站系统需要涉及到用户登录、发布动态、关注、评论、私信等各方面。这里提供一个简单的实现示例,供参考。 前端代码 前端使用Vue框架,以下是部分代码示例: 登录页: <template><div><input type…...
Modbus转Profinet网关连接三菱变频器博图快速配置
本案例将分享如何使用兴达易控的modbus转profinet网关(XD-MDPN100)来连接西门子1200系列plc,并实现三菱变频器的485通讯兼容转modbusTCP通信。通过在博图中进行配置,我们可以实现设备之间的连接和通信。 首先,我们需要…...
8.9 【C语言】有关指针的小结
(1)首先要准确理解指针的含义。 &a是变量a的地址,也可称为变量a的指针。 指针变量是存放地址的变量。 指针变量的值是一个地址。 指针变量也称为地址变量,它的值是地址。 (2)在C语言中,…...
WordPress Nginx伪静态规则设置以及二级目录规则
WordPress Nginx伪静态规则设置以及二级目录规则(wordpress不是安装在根目录的情况) 根目录下WordPress的伪静态规则: location / {if (-f $request_filename/index.html){rewrite (.*) $1/index.html break;}if (-f $request_filename/ind…...
2023年高教社杯 国赛数学建模思路 - 复盘:人力资源安排的最优化模型
文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 描述 …...
React内置函数之startTransition与useTransition
React内置函数之startTransition,useTransition 在React中,使用startTransition和useTransition这两个内置函数可以帮助我们更好地管理组件的过渡状态。这两个函数的出现,旨在提供一种简单而强大的方式,来处理组件状态的变化&…...
观察者模式简介
概念: 观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,其相关依赖对象会自动收到通知并进行相应处理。 特点: 松耦合&a…...
统计程序两个点之间执行的指令数量
环境:支持perf ubuntu安装 apt-get install linux-tools-common linux-tools-generic linux-tools-uname -randroid 一般自带simpleperf 分析 两个点作差, 求中间结果; *(int*)nullptr 0;案例 断点 1 代码 #define SETPOINT(...) do { *(int*)nullptr 0; } while(0…...
时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价)
时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价) 目录 时序预测 | MATLAB实现基于TSO-XGBoost金枪鱼算法优化XGBoost的时间序列预测(多指标评价)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现基于TSO-XGBoost金枪鱼算…...
java- ConcurrentHashMap 并发
1. ConcurrentHashMap 并发 1.1. 减小锁粒度 减小锁粒度是指缩小锁定对象的范围,从而减小锁冲突的可能性,从而提高系统的并发能力。减小锁粒度是一种削弱多线程锁竞争的有效手段,这种技术典型的应用是 ConcurrentHashMap(高性能的 HashMap)…...
java练习8.100m小球落地
题目: 如一个小球从100米高度自由落下,每次落地后就反跳回原高度的一半。 那么求它在第10次落地时,共经过多少米?第10次反弹多高? public static void main(String[] args) {/*假如一个小球从100米高度自由落下,每次落…...
Android JNI系列详解之生成指定CPU的库文件
一、前提 这次主要了解Android的cpu架构类型,以及在使用CMake工具的时候,如何指定生成哪种类型的库文件。 如上图所示,是我们之前使用CMake工具默认生成的四种cpu架构的动态库文件:arm64-v8a、armeabi-v7a、x86、x86_64࿰…...
Leetcode每日一题:1448. 统计二叉树中好节点的数目
原题 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例 1: 输入:root [3,1,4,3,null,1,5] 输出:4 解…...
华为OD七日集训第2期 - 按算法分类,由易到难,循序渐进,玩转OD(文末送书)
目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第2期五、精心挑选21道高频100分经典题目,作为入门。第1天、逻辑分析第2天、字符串处理第3天、数据结构第4天、递归回溯第5天、二分查找第6天、深度优先搜索dfs算法第7天、动态规划 六、集训总结1、《代码…...
3d max插件CG MAGIC中的蜂窝材质功能可提升效率吗?
工作中能提升效率也都是大家所想的,对于设计师的一个设计过程中,可能想怎么样可以更快呀,是哪个步骤慢了呢? 这样的结果只能说会很多,但是建模这个步骤,肯定是有多无少的。 为了让模型更加逼真,…...
一句话木马攻击复现:揭示黑客入侵的实战过程
这篇文章旨在用于网络安全学习,请勿进行任何非法行为,否则后果自负。 准备环境 OWASP虚拟机xfp 7与xshell 7 DVWA系统默认的账号密码均为:admin/admin 1、命令注入中复现 攻击payload 127.0.0.1 | echo "<?php eval(…...
【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 | 新发出品 | 良心教程)
文章目录 一、前言二、插件下载三、案例1:第三人称自由视角,Free Look character场景1、场景演示2、组件参数2.1、CinemachineBrain:核心2.2、CinemachineFreeLook:第三人称自由视角相机2.2.1、设置Follow:跟随2.2.2、…...
当图像宽高为奇数时,如何计算 I420 格式的uv分量大小
背景 I420 中 yuv 数据存放在3个 planes 中。 网上一般说 I420 数据大小为 widthheight1.5 但是当 width 和 height 是奇数时,这个计算公式会有问题。 I420 中 u 和 v 的宽高分别为 y 的一半。 但是当不能整除时,是如何取整呢?向上还是向下&…...
结构型模式-代理模式
代理模式* 定义:在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 意图:为其…...
SpringBoot+Redis BitMap 实现签到与统计功能
最近项目里需要集成签到和统计功能,连续签到后会给用户发放一些优惠券和奖品,以此来吸引用户持续在该品台进行活跃。下面我们一些来聊一聊目前主流的实现方案。 因为签到和统计的功能涉及的数据量比较大,所以在如此大的数据下利用传统的关系…...
P5739 【深基7.例7】计算阶乘
题目描述 求 n ! n! n!,也就是 1 2 3 ⋯ n 1\times2\times3\dots\times n 123⋯n。 挑战:尝试不使用循环语句(for、while)完成这个任务。 输入格式 第一行输入一个正整数 n n n。 输出格式 输出一个正整数,…...
scikit-learn中OneHotEncoder用法
One-Hot编码,又称为一位有效编码,是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值,然后,每个整数值被表示为二进制向量,将整数索引标记为1,其余都标为0。 OneHotEncoder()常用参数解释 …...
linux操作系统的权限的深入学习(未完)
1.Linux权限的概念 Linux下有两种用户:超级用户(root)、普通用户。 超级用户:可以再linux系统下做任何事情,不受限制 普通用户:在linux下做有限的事情。 超级用户的命令提示符是“#”,普通用户…...
C 连接MySQL8
Linux 安装MySQL 8 请参考文章:Docker 安装MySQL 8 详解 Visual Studio 2022 编写C 连接MySQL 8 C源码 #include <stdio.h> #include <mysql.h> int main(void) {MYSQL mysql; //数据库句柄MYSQL_RES* res; //查询结果集MYSQL_ROW row; //记录结…...
福利之舞:员工的心跳与企业的平衡术
引言:员工福利与满意度的关系 在现代企业中,员工福利已经不仅仅是一种待遇,而是与员工满意度、忠诚度和生产力紧密相连的关键因素。一个合理且吸引人的福利制度可以大大提高员工的工作积极性,同时也能够吸引和留住顶尖的人才。但…...
MyBatis动态语句且如何实现模糊查询及resultType与resultMap的区别---详细介绍
前言 前面我们学习了如何使用Mybatis实现简单的增删改查。今天我们来学习如何使用动态语句来根据不同的条件生成不同的SQL语句。这在实际开发中非常有用,因为通常查询条件是多样化的,需要根据实际情况来拼接SQL语句,那什么是MyBatis动态语句呢…...
麒麟OS国产系统身份证阅读器web网页开发使用操作流程
1、打开麒麟软件商店,选择驱动,找到身份证阅读器,找到东信智能身份证社保卡读卡器,点击安装。 2、安装完成后,点击打开 3、进入读卡界面 4、进入代码集成 <script type"text/javascript">var ctnFin…...
前端面试:【事件处理】探索事件流、委托与事件对象
嗨,亲爱的事件探险家!在JavaScript的世界中,事件处理是与用户互动的关键。本文将带你探索事件流、事件委托、常见事件类型和事件对象,这些知识将帮助你成为事件处理的大师。 2. 事件流:事件的旅程 事件流描述了事件从…...
烟台seo网站诊断/seo外包公司费用
晚上忽然发现自己的MAC从运行程序到看到Spring boot日志时间超过20秒。新建个空的boot空工程也需要10秒才会看到boot的启动日志。 最后设置了gc日志看了下有无异常情况。 从jvisualvm看下 Java HotSpot(TM) 64-Bit Server VM (25.131-b11) for bsd-amd64 JRE (1.8.0_131…...
门户网站开发jz190/关键词收录
双节锂电池充电芯片IC,5V升压FS4059A,9V降压FS7222 详情 FS4059A USB 5V输入,升压给双节锂电池充电芯片IC 支持USB输入:5V2A最大。智能兼容5V1A,0.5A充电器,兼容不拉垮充电器。 (输出端,即电池端&#…...
wordpress o2o插件/石景山区百科seo
上次讲到的是CSVread函数来获取测试数据的参数化,这次使用randomstring 有的时候有些参数是不断变化的,我们如果利用csv去做,还是要准备很多不同的数据,但是我们如果用randomstring的话,那么就可以减少这个问题的干扰。 步骤: 准备好csV格式的数据准备…...
企业建设网站需要什么资料/seo常用分析的专业工具
一个程序猿的生命周期 微信平台 口 号:职业交流,职业规划;面对现实,用心去交流、感悟。 公众号:iterlifetime 百木-ITer职业交流奋斗 群:141588103 微 博:http://www.weibo.com/u/57234…...
商城网站 后台/网站seo设置是什么
我正在为我的项目准备一个酒店预订页面,但是我很难把表格弄好。我有许多输入字段,我当前的代码只是使它成为一个非常长的页面。我的预订单基本上有两部分:客户信息和房间偏好。我想把左边的客户信息和右边的房间偏好对齐。因为我计划验证表单,所以我希望它是相同的 My form cur…...
合作网站开发/业务推广方式
起步 首先你需要在服务器安装宝塔服务,通过宝塔下载软件。 下载软件 去宝塔的软件商店下载PM2管理器和MongoDB数据库。 去你的服务器把你自己的后端端口放行一下,不然运行无法请求到 我这里设置的是3000端口,所以需要把3000端口加入到你…...