一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

单词或词段词元化的推断方法与流程

2022-10-26 20:59:03 来源:中国专利 TAG:

单词或词段词元化的推断方法


背景技术:

1.自然语言处理(“nlp”)技术利用各种形式的词元化(tokenization)来将文本转换成词元的集合。例如,词元化器可以通过在空白字符(例如,空格、段落标记)和标点字符处分割文本来将给定的文本样本变成一系列单词,并且可以通过移除重音标记和其他非标准字符以及将大写字母改变成小写字母来进一步处理单词。在一些nlp技术中,诸如来自变换器的双向编码器表示(“bert”),文本的每个单词可以被进一步分解成子单词单元,本文中称为词段(wordpiece)。同样,在单词没有被空格分隔的书面语言(例如,中文)中,nlp技术可以使用相同的过程来将表示多个单词的字符串分解成各自表示单个单词的片段。该过程,在本文中被称为单词或词段推断,可以由词元化器执行,该词元化器使用已知单词或词段的词汇表来识别每个字符串中的单独单词或词段。


技术实现要素:

2.本技术涉及使用从左到右最长匹配优先贪婪过程(或“正向最大匹配”过程)来执行单词或词段推断的系统和方法,其中每个输入串被分解成从左到右移动的最长匹配词元(例如,对于是单个单词的输入串,是最长匹配前缀和后缀词元)。对此,并且如下面进一步讨论的,在本技术的一些方面,词元化器的词汇表可以被组织成特里(trie)结构,其中每个节点包括预先计算的词元或token_id以及失效(fail)链接,使得词元化器能够在单遍中解析特里,以生成仅对应于样本单词中最长匹配前缀和后缀词段的那些词元或token_id的列表,而不需要回溯。类似地,在本技术的一些方面,词元化器的词汇表可以被组织成特里结构,其中每个节点具有失效链接,并且任何将共享前一节点的(多个)词元或(多个)token_id的节点改为被给予prev_match链接,该prev_match链接指回具有那些词元或token_id的一个或多个祖先节点的链,从而使词元化器能够在单遍中解析特里,并且在每次失效时跟随prev_match链接以收集词元或token_id,如下面进一步讨论的。
3.在一个方面,本公开描述了一种计算机实现的方法,包括:由处理系统的一个或多个处理器执行文本的串的词元化;以及由一个或多个处理器将词元阵列提供给用于自然语言处理的神经网络。对此,执行文本的串的词元化包括:分析词汇表特里结构的第一节点,并且标识词汇表特里结构的第一节点和第二节点之间的对应于串的第一字符的链接;基于第一节点和第二节点之间的链接,确定不存储与第一节点相关联的词元;分析第二节点,并且标识词汇表特里结构的第二节点和第三节点之间的对应于串的第二字符的链接;基于第二节点和第一节点之间的链接,确定不存储与第二节点相关联的词元;分析第三节点以确定第三节点没有对应于串的第三字符的链接,并且标识词汇表特里结构的第三节点和第四节点之间的失效链接;存储与第三节点相关联的第一词元,该第一词元表示由串的第一字符和第二字符组成的单词或词段;分析第四节点以确定第四节点没有对应于串的第三字符的链接;存储与第四节点相关联的第二词元,该第二词元表示由串的第三字符组成的单词或词段;以及串接第一词元和第二词元以形成词元阵列。在一些方面,第一词元包括包含串的第一字符和第二字符的单词或词段,并且第二词元包括串的第三字符。在一些方面,第一
词元标识词汇表中包括串的第一字符和第二字符的单词或词段的条目,并且第二词元标识词汇表中串的第三字符的条目。在一些方面,该字符串还包括第四字符,并且在其它的方面,该第四字符是表示串的结束的符号。
4.在另一方面,本公开描述了一种计算机实现的方法,包括:由处理系统的一个或多个处理器执行文本的串的词元化;以及由一个或多个处理器将词元阵列提供给用于自然语言处理的神经网络。对此,执行文本的串的词元化包括:分析词汇表特里结构的第一节点,并且标识词汇表特里结构的第一节点和第二节点之间的对应于串的第一字符的链接;基于第一节点和第二节点之间的链接,确定不存储词元;分析第二节点,并且标识词汇表特里结构的第二节点和第三节点之间的对应于串的第二字符的链接;基于第二节点和第一节点之间的链接,确定不存储词元;分析第三节点,并且标识词汇表特里结构的第三节点和第四节点之间的对应于串的第三字符的链接;基于第三节点和第四节点之间的链接,确定不存储词元;分析第四节点,并且标识词汇表特里结构的第四节点和第五节点之间的对应于串的第四字符的链接;基于第四节点和第五节点之间的链接,确定不存储词元;分析第五节点以确定第五节点没有对应于字符串的第五字符的链接,并且标识词汇表特里结构的第五节点和第六节点之间的失效链接,以及第五节点和第三节点之间的先前匹配链接;存储与第三节点相关联的第一词元,该第一词元表示由串的第一字符和第二字符组成的单词或词段;存储与第五节点相关联的第二词元,该第二词元表示由串的第三字符组成的单词或词段;分析第六节点以确定第六节点没有对应于串的第五字符的链接,并且没有先前匹配链接;存储与第六节点相关联的第三词元,该第三词元表示由串的第四字符组成的单词或词段;以及串接第一词元、第二词元和第三词元以形成词元阵列。在一些方面,第一词元包括包含串的第一字符和第二字符的单词或词段,第二词元包括串的第三字符,并且第三词元包括串的第四字符。在一些方面,第一词元标识词汇表中包括串的第一字符和第二字符的单词或词段的条目,第二词元标识词汇表中串的第三字符的条目,并且第三词元标识词汇表中串的第四字符的条目。在一些方面,串还包括第五字符,并且在其它的方面,第五字符是表示串的结束的符号。
5.在另一方面,本公开描述了一种处理系统,包括:存储器;以及耦合到存储器的一个或多个处理器,其被配置为执行文本的串的词元化,并将词元阵列提供给用于自然语言处理的神经网络。对此,执行文本的串的词元化包括:分析词汇表特里结构的第一节点,并且标识词汇表特里结构的第一节点和第二节点之间的对应于串的第一字符的链接;基于第一节点和第二节点之间的链接,确定不存储与第一节点相关联的词元;分析第二节点,并且标识词汇表特里结构的第二节点和第三节点之间的对应于串的第二字符的链接;基于第二节点和第一节点之间的链接,确定不存储与第二节点相关联的词元;分析第三节点以确定第三节点没有对应于字符串的第三字符的链接,并且标识词汇表特里结构的第三节点和第四节点之间的失效链接;存储与第三节点相关联的第一词元,该第一词元表示由字符串的第一字符和第二字符组成的单词或词段;分析第四节点以确定第四节点没有对应于串的第三字符的链接;存储与第四节点相关联的第二词元,该第二词元表示由字符串的第三字符组成的单词或词段;以及串接第一词元和第二词元以形成词元阵列。在一些方面,第一词元包括包含串的第一字符和第二字符的单词或词段,并且第二词元包括串的第三字符。在一些方面,第一词元标识词汇表中包括串的第一字符和第二字符的单词或词段的条目,并且
第二词元标识词汇表中串的第三字符的条目。在一些方面,该字符串还包括第四字符,并且在其它的方面,该第四字符是表示串的结束的符号。
6.在另一方面,本公开描述了一种处理系统,包括:存储器;以及耦合到存储器的一个或多个处理器,其被配置为执行文本的串的词元化,并且将词元阵列提供给用于自然语言处理的神经网络。对此,执行文本的串的词元化包括:分析词汇表特里结构的第一节点,并且标识词汇表特里结构的第一节点和第二节点之间的对应于串的第一字符的链接;基于第一节点和第二节点之间的链接,确定不存储词元;分析第二节点,并且标识词汇表特里结构的第二节点和第三节点之间的对应于串的第二字符的链接;基于第二节点和第一节点之间的链接,确定不存储词元;分析第三节点,并且标识第三节点和词汇表特里结构的第四节点之间的对应于串的第三字符的链接;基于第三节点和第四节点之间的链接,确定不存储词元;分析第四节点,并且标识词汇表特里结构的第四节点和第五节点之间的对应于串的第四字符的链接;基于第四节点和第五节点之间的链接,确定不存储词元;分析第五节点以确定第五节点没有对应于字符串的第五字符的链接,并且标识词汇表特里结构的第五节点和第六节点之间的失效链接,以及第五节点和第三节点之间的先前匹配链接;存储与第三节点相关联的第一词元,该第一词元表示由串的第一字符和第二字符组成的单词或词段;存储与第五节点相关联的第二词元,该第二词元表示由字符串的第三字符组成的单词或词段;分析第六节点以确定第六节点没有对应于串的第五字符的链接,并且没有先前的匹配链接;存储与第六节点相关联的第三词元,该第三词元表示由字符串的第四字符组成的单词或词段;以及串接第一词元、第二词元和第三词元以形成词元阵列。在一些方面,第一词元包括包含字符串的第一字符和第二字符的单词或词段,第二词元包括串的第三字符,并且第三词元包括串的第四字符。在一些方面,第一词元标识词汇表中包括串的第一字符和第二字符的单词或词段的条目,第二词元标识词汇表中串的第三字符的条目,第三词元标识词汇表中串的第四字符的条目。在一些方面,串还包括第五字符,并且在其它的方面,第五字符是表示串的结束的符号。
附图说明
7.图1是根据本公开的各方面的示例系统的功能图。
8.图2a描绘了根据本公开的各方面的示例性词汇表和对应的特里结构。
9.图2b描绘了根据本公开的各方面的示例性词汇表和对应的特里结构。
10.图3a至图3c是根据本公开的各方面的构建特里结构的示例性方法的流程图。
11.图4是根据本公开的各方面的使用特里结构执行词元化的示例性方法的流程图。
12.图5a描绘了根据本公开的各方面的示例性词汇表和对应的特里结构。
13.图5b描绘了根据本公开的各方面的示例性词汇表和对应的特里结构。
14.图6a至图6c是根据本公开的各方面的构建特里结构的示例性方法的流程图。
15.图7是根据本公开的各方面的使用特里结构执行词元化的示例性方法的流程图。
具体实施方式
16.现在将参考以下示例性系统和方法来描述本技术。
17.示例系统
18.图1中示出了根据本技术的各方面的高级系统图100。处理系统102包括一个或多个处理器104以及存储指令108和数据110的存储器106。数据110包括原始文本120的集合、自然语言处理模型112和标识的单词或词段122的集合。自然语言处理模型112包括词元化器114、词汇表116和基于词汇表116内容的特里结构118。如下面进一步解释的,词元化器114可以使用特里结构118从原始文本120中生成该标识的单词或词段122的集合。在该技术的一些方面,词汇表116可以是通过在未标记的数据上训练词元化器114而生成的学习词汇表。
19.处理系统102可以在任何类型的(多个)计算设备上实现,诸如任何类型的通用计算设备、服务器或其集合,并且还可以包括通常存在于通用计算设备或服务器中的其他组件。存储器106存储可由一个或多个处理器104访问的信息,包括可由(多个)处理器104执行或以其他方式使用的指令108和数据110。存储器106可以是能够存储可由(多个)处理器104访问的信息的任何非暂时性类型。例如,存储器106可以包括非暂时性介质,诸如硬盘驱动器、存储卡、光盘、固态、磁带存储器等。适合于本文中描述的角色的计算设备可以包括前述的不同组合,由此指令和数据的不同部分被存储在不同类型的介质上。
20.在所有情况下,本文中描述的计算设备还可以包括通常结合计算设备使用的任何其他组件,诸如用户界面子系统。用户界面子系统可以包括一个或多个用户输入(例如,鼠标、键盘、触摸屏和/或麦克风)和一个或多个电子显示器(例如,具有屏幕的监视器或可操作来显示信息的任何其他电子设备)。除了电子显示器之外的输出设备,诸如扬声器、灯以及振动、脉冲或触觉元件,也可以被包括在本文中描述的计算设备中。
21.包括在每个计算设备中的一个或多个处理器可以是任何传统的处理器,诸如商业上可获得的中央处理单元(“cpu”)、图形处理单元(“gpu”)、张量处理单元(“tpu”)等。替代地,一个或多个处理器可以是专用设备,诸如asic或其他基于硬件的处理器。每个处理器可以具有能够并行操作的多个内核。单个计算设备的(多个)处理器、存储器和其他元件可以被存储在单个物理外壳内,或者可以被分布在两个或更多个外壳之间。类似地,计算设备的存储器可以包括位于不同于(多个)处理器的外壳的外壳中的硬盘驱动器或其他存储介质,诸如在外部数据库或网络存储设备中。因此,对处理器或计算设备的引用将被理解为包括对可以或可以不并行操作的处理器或计算设备或存储器的集合的引用,以及对负载平衡的服务器群或基于云的系统的一个或多个服务器的引用。
22.本文中描述的计算设备可以存储能够由(多个)处理器直接执行(诸如机器代码)或间接执行(诸如脚本)的指令。计算设备还可以存储数据,该数据可以由一个或多个处理器根据指令检索、存储或修改。指令可以作为计算设备代码被存储在计算设备可读介质上。对此,术语“指令”和“程序”在这里可以互换使用。指令也可以以目标代码格式存储,以用于由(多个)处理器直接处理,或者以任何其他计算设备语言存储,包括按需解释或预先编译的独立源代码模块的脚本或集合。举例来说,编程语言可以是c#、c 、java或其他计算机编程语言。类似地,指令或程序的任何组件可以用计算机脚本语言实现,诸如javascript、php、asp或任何其他计算机脚本语言。此外,这些组件中的任何一个都可以使用计算机编程语言和计算机脚本语言的组合实现。
23.计算设备可以包括语音识别引擎,该语音识别引擎被配置成将由用户输入到与计算设备相关联的麦克风的语音转换成文本数据。这种输入可以是针对例如可通过计算设备
访问的自动化助理的用户查询。从用户语音输入生成的文本数据可以使用本文中描述的任何方法处理,以将文本数据词元化以供进一步处理。例如,可以对词元化的文本数据进行处理,以提取用户语音输入中存在的对自动化助理的查询。该查询可以被发送给自动化助理,该自动化助理继而可以响应于该查询经由计算设备向用户提供一个或多个服务。
24.示例方法
25.除了上面描述的和附图中图示的系统之外,现在将描述各种操作。为了清楚起见,本文中描述的和在图2至图9中描述的示例性方法都假设输入串将是单词,并且词汇表将由词段组成,词段由来自英语(或拉丁语)字母表的字母串组成。然而,本技术能够被应用于任何书面语言。此外,对此,由于诸如中文的一些书面语言不在单词之间插入空格,本技术可以被用于将表示多个单词的字符串分解成各自表示单个单词的片段。在这种情况下,本技术将以与以下示例中描述的方式相同的方式操作,但是输入文本将是表示多个中文单词的字符串(而不是表示单个单词的字符串),并且输出将是词元阵列,每个词元阵列标识在输入串中找到的单个中文单词(而不是词元阵列,每个词元阵列标识在输入串中找到的词段)。
26.对此,有多种方式可以配置处理系统将给定的文本的串转换成最长的已知词段。例如,处理系统可以被配置为使用从右到左的强力方法,其中首先在词汇表中查找每个单词,如果该单词不存在,则将其减少一个字符,并且该过程被重复。在这样的范例中,一旦词段被定位,它就被标识为前缀,然后处理系统处理跟随第一词段的字符,直到它在剩余的词段中定位最大的后缀词段。使用这种从右到左的强力方法,可以如下面的表1所示处理单词“unknownable”:
27.表1:
28.[0029][0030]
从上面的表1中能够看出,在这种情况下,从右到左的强力方法在十五次查询中标识出三个已知的词段。然而,在最坏的情况下,具有n个字符的单词最终不包含任何大于单个字符的已知词段,处理系统将不得不执行n(n 1)/2个分开的查询来处理整个单词,使得推断时间为n2的数量级。
[0031]
同样,在另一示例中,处理系统可以被配置为使用从左到右的强力方法,其中在词汇表中查找单词的第一字母,然后是第一和第二字母,然后是第一至第三字母,以此类推,直到找到最长的匹配前缀。在这样的范例中,一旦词段被定位,它就被标识为前缀,然后处理系统处理第一词段之后的字符,直到它在剩余的词段中定位一个或多个最大的后缀词段。使用这种从左到右的强力方法,可以如下面的表2所示处理单词“unknowable”:
[0032]
表2:
[0033]
[0034]
[0035][0036]
从上面的表2能够看出,在这种情况下,从左到右的强力方法在16次查询的过程中标识出三个已知的词段。然而,同样在这种情况下,当具有n个字符的单词最终不包含任何大于单个字符的已知词段时,处理系统将不得不再次执行n(n 1)/2个分开的查询来处理整个单词,使得推断时间为n2的数量级。
[0037]
同样,在另一示例中,处理系统可以被配置成使用aho-corasick串搜索算法。aho-corasick算法能够被用于将词汇表转换成具有后缀链接和词典后缀链接的特里结构。然后能够解析该特里结构,以标识匹配一段输入文本的所有已知串。例如,如果词汇表包括{a,ab,bab,bc,bca,c,caa},处理输入串“abccab”的aho-corasick算法将标识该输入串中的每个可能的匹配项,包括与其他匹配项重复或重叠的匹配项,从而产生{a,ab,bc,c,c,a,ab}的输出。因此,对于依赖于从左到右最长匹配优先的词段词元化贪婪过程的nlp技术,aho-corasick算法标识比所需更多的匹配项,需要另外的后处理步骤来将所有匹配词段的列表减少到仅最大匹配前缀和每个下一最长后缀。此外,在最坏的场景下,给定的n个字符的单词中的每个子串都匹配词汇表中的词元,推断时间为n2的数量级。
[0038]
相反,在本技术中,处理系统102被配置成使用修改后的特里结构118。在这一点上,在本技术中,特里118不是被设计成标识给定文本样本中的所有已知词段,而是被配置成仅标识最长的已知前缀和每个下一最长的后缀,直到样本文本中没有更多要被匹配的字符。结果,本技术能够比上述示例更快地标识最长的前缀和后缀词元。更具体地说,本技术能够使n个字符的单词的推断时间为n的数量级。
[0039]
图2a描绘了根据本技术的各方面的示例性词汇表和对应的特里结构。在图2a的示例中,词汇表200a包含六个词段:a;ab;abcd;abczd;##c;和##z。如上所述,“##”是后缀指示符,表示所讨论的词段开始于单词的中间,因此在任何匹配的文本样本中,其前面必须至少有一个字符。同样,“$”是用于标识输入串的结束的字符。在该示例中,词汇表200a被转换成特里结构201a。特里结构201a可以被体现为适合于由词元化器114处理的任何数据结构。然而,为了解释的目的,结构201a在图2a中被图示。对此,图2a中的每个圆圈(例如,附图标记202)表示特里结构201a中的节点。每个圆形节点在顶部具有数字的node_id(例如,附图标记204),和底部括号中的一个或多个词段(例如,附图标记206a),这些词段是为该节点预先
计算的全弹出词元。带有“[]”的节点没有与之关联的全弹出词元。
[0040]
特里结构201a的实线箭头(例如,附图标记208)表示转到(goto)链接,并且每个箭头(例如,附图标记210)旁边的字符表示跟随该转到链接的条件。因此,假设处理系统102的词元化器114正尝试对“abcz$”进行词元化,它将通过分析具有node_id 0的根节点开始以确定它是否具有对应于“abcz$”的第一字符的转到链接开始。在这种情况下,因为存在以从根节点延伸的“a”为条件的转到链接208,所以词元化器114将标识转到链接208,并具有node_id 3的节点跟随它。
[0041]
特里结构201a的虚线箭头(例如,附图标记212)表示失效链接。因此,继续同一示例,因为“abcz$”的第二字符是“b”,所以词元化器114将分析具有node_id 3的节点,并标识“b”的转到链接。词元化器114因此将跟随“b”的转到链接以到达具有node_id 4的节点。同样,由于“abcz$”的第三字符是“c”,词元化器114将标识“c”的转到链接,并跟随它以到达具有node_id 5的节点。类似地,由于“abcz$”的第四字符是“z”,词元化器114将标识“z”的转到链接,并跟随它以到达具有node_id 7的节点。然而,当词元化器114分析具有node_id 7的节点时,它将不能标识对应于“abcz$”的第五字符的转到链接。因此,词元化器114将反而收集(例如,存储在变量中)它未能继续前进的节点(具有node_id 7的节点)的预先计算的全弹出词元(“ab”和“##c”),然后将跟随该节点的失效链接212到达具有node_id 10的节点。因为词元化器114仅当不能使用转到链接到达下一节点时收集全弹出词元,所以所收集的词元自动表示匹配词汇表200a中已知词段的样本文本的最长片段。因此,在该示例中,词汇表200a中的“abcz$”内的最长前缀被标识为“ab”,紧随“ab”的最长后缀被标识为“##c”。
[0042]
继续同一示例,在跟随失效链接212以到达具有node_id 10的节点之后,词元化器114将尝试跟随下一转到链接。然而,由于具有node_id 10的节点没有其它的转到链接,词元化器114将被迫再次收集该节点的全弹出词元(“##z”),并跟随其失效链接到具有node_id2的节点。该全弹出词元与被收集的先前的全弹出词元串接,以生成三个全弹出词元的阵列(“ab”、“##c”、“##z”)。
[0043]
一旦到达具有node_id 2的节点,词元化器114将试图找到“abcz$”的第五字符“$”的转到链接。如前所述,“$”字符是一个特殊字符,表示输入串的结束。由于特里结构201a被配置有专用于输入结束字符“$”的转到链接,词元化器114将跟随该链接以到达具有node_id 11的节点。由于在“abcz$”中没有其它的字符要处理,词元化器114将停止解析特里结构201a。因此,该过程将以现有的三个全弹出词元的阵列(“ab”、“##c”、“##z”)结束。
[0044]
尽管本文中阐述的示例利用了输入结束字符,但是本技术并不要求这样。因此,在该技术的一些方面,在特里结构中将没有输入结束字符,也没有与其对应的节点,并且当单词中没有更多要被处理的实际字符时,词元化器114将简单地停止解析。对此,在刚刚描述的示例中,如果词元化器尝试对“abcz”而不是“abcz$”进行词元化,那么在跟随“z”的转到链接以到达具有node_id 7的节点(此时将没有其它的字符要处理)之后,词元化器将收集该节点的全弹出词元(“ab”、“##c”),并且递归地跟随来自具有node_id 7的节点的失效链接,并且收集这些链接节点的任何全弹出词元。因此,在这种情况下,词元化器114将跟随失效链接212以到达具有node_id 10的节点。然后,词元化器将收集具有node_id 10的节点的全弹出词元(“##z”),并跟随它的失效链接到具有node_id 2的节点。当它到达表示后缀指示符“##”的具有node_id 2的节点时,该过程将结束。值得注意的是,这将导致三个全弹出
词元的相同阵列(“ab”、“##c”、“##z”)。然而,如果词元化器114在到达后缀指示符节点(具有node_id 2的节点)之前遇到空的失效链接,这将指示输入单词不能被成功词元化。在这种情况下,词元化器114会将整个单词映射到单个词元,例如“《unk》”,这指示该单词是未知的,然后该过程会结束。
[0045]
在某些情况下,一个节点可以有一个空的失效链接。例如,根节点(具有node_id 0的节点)和后缀根节点(具有node_id 2的节点)的失效链接都有空的失效链接。为了说明的目的,这些空的失效链接在图2a中被表示为指向利用附图标记214标识的矩形“空”(“null”)框的虚线箭头。
[0046]
将理解,本文中使用的示例词汇表、词段和单词仅用于说明目的。对此,取决于被词元化的串的大小和可用的词元,词元化器114可以输出具有任意数量的全弹出词元的阵列。
[0047]
图2b还描绘了根据本技术的各方面的示例性词汇表和对应的特里结构。在图2b的示例中,词汇表200b与图2a的词汇表200a相同,除了词汇表200b中的每个单词还与对应的token_id相关联。例如,词汇表200b中的第一词段“a”与token_id“1”相关联。同样,图2b的特里结构200b与图2a的特里结构200a相同,并且将以相同的方式被构造,除了特里结构200b的每个节点包含括号中的数字全弹出token_id(例如,附图标记206b)而不是全弹出词元的文本。在图2b的示例中,全弹出token_id能够与词汇表200b结合使用,以确定相关联的全弹出词元的文本。除了刚刚描述的差异,图2a和图2b的特里结构是相同的,并且两个图之间所有共同的附图标记表示相同的特征。因此,词元化器114将以与以上关于图2a的特里结构201a描述的相同的方式解析图2b的特里结构201b,但是不是收集每个全弹出词元的文本,它将收集数字全弹出token_id。因此,在图2b的示例中,在词元化器114到达具有node_id 11的节点并且没有更多字符要处理之后,它将停止解析特里结构201b,并且然后使用收集的全弹出token_id(2、5、6)来标识对应的全弹出词元(ab、##c、##z)。
[0048]
图3a至图3c是构建图2a和图2b的示例中所示类型的特里结构的示例性方法的流程图。因此,从图3a所示的方法300开始,在步骤302中,将创建根节点(图2a和图2b中具有node_id 0的节点)和后缀根节点(图2a和图2b中具有node_id 2的节点),并且将以后缀指示符为条件在它们之间创建转到链接。然而,由于图2a和图2b的示例采用了包括两个连续井号(“##”)的后缀指示符,所以还需要在根节点和后缀根节点之间创建中间节点来表示单个“#”字符。然后,第一转到链接将从根节点被延伸到以“#”为条件的“#”节点(具有node_id 1的节点),并且以“#”为条件的第二转到链接将从“#”节点被延伸到后缀根节点。本技术不需要使用“##”作为后缀指示符。对此,可以使用任何其他合适的后缀指示符,包括使用其他字符、单个字符、多个字符等的后缀指示符。另外,在本技术的一些方面,后缀指示符可以从词汇表的词段中省略,并且对应的特里结构因此可以具有空的后缀指示符(例如,具有node_id 2的节点将折叠成具有node_id 0的节点),或者后缀指示符可以从特里结构中完全省略。例如,在本技术被用于中文分词的情况下,采用空的后缀指示符可能是有利的。
[0049]
在步骤304,将为词汇表中的每个前缀词段创建节点,并且每个这样的节点将经由以该字符为条件的转到链接被连接到根节点。因此,在图2a的示例中,因为词汇表200a中的所有前缀词段都以字母“a”开始,所以在该步骤中将只创建一个节点,和从根节点(具有node_id0的节点)到“a”的节点(具有node_id 3的节点)的一个转到链接。
[0050]
在步骤306,将为词汇表中每个前缀词段的下一字符创建节点,并且每个这样的节点将经由以该下一字符为条件的转到链接被连接到其前一字符的节点。因此,在图2a的示例中,因为词汇表200a中以字母“a”开始的所有单词都具有第二字符“b”,所以将只有从“a”的节点延伸到“ab”的节点(具有node_id 4的节点)的一个转到链接。尽管图2a的示例中的词汇表只包含以“a”开始的词段,但是如果它包含以诸如“b”的另一字符开始的词段,那么将重复该相同的过程,以便创建表示所有这样的以“b”开始的词段的分支。同样,如果词汇表包括一个或多个以单个“#”字符开始的前缀词段,分支也可以从具有node_id 1的节点延伸。
[0051]
在步骤308中,将对词汇表中每个前缀词段的每个下一字符重复步骤306的过程,直到每个前缀词段已经被特里结构中的节点完全表示。因此,在图2a的示例中,因为词汇表200a中以字母“ab”开始的所有词段都具有第三字符“c”,所以只有从“ab”的节点延伸到“abc”的节点(具有node_id 5的节点)的一个转到链接。相反,因为词汇表200a中以“abc”开始的词段能够具有“d”或“z”作为它们的第四字符,所以将有从“abc”的节点延伸的两个转到链接——一个延伸到“abcd”的节点(具有node_id 6的节点),和一个延伸到“abcz”的节点(具有node_id 7的节点)。最后,转到链接将从“abcz”的节点被延伸到“abczd”的节点(具有node_id 8的节点),以表示词汇表200a中以“a”开始的最后剩余词段。
[0052]
在步骤310,将为词汇表中的每个后缀词段创建节点,并且每个这样的节点将经由以后缀指示符之后的第一字符为条件的转到链接被连接到后缀根节点。因此,在图2a的示例中,将为“##c”创建节点,并且它将经由以“c”为条件的转到链接被连接到后缀根节点。同样,将为“##z”创建节点,并且它将经由以“z”为条件的转到链接被连接到后缀根节点。
[0053]
在步骤312,将为词汇表中每个后缀词段的下一字符创建节点,并且每个这样的节点将通过以该下一字符为条件的转到链接被连接到其前一字符的节点。如步骤314所示,将对词汇表中每个后缀词段的每个下一字符重复步骤312的过程,直到每个后缀词段都已被特里结构中的节点完全表示。然而,在图2a的示例中,由于词汇表仅包含带有后缀指示符后的单个字符的后缀词段,所以分支将不会延伸超过根据步骤310创建的“##c”和“##z”节点。
[0054]
最后,在步骤316和318,将为输入结束字符创建节点。对此,在步骤316,第一这样的节点将被创建,并经由以输入结束字符为条件的转到链接被连接到根节点。因此,在图2a的示例中,具有node_id12的节点将被创建,并且转到链接将从以字符“$”为条件的根节点被延伸到该节点。同样,在步骤318,第二这样的节点将被创建,并经由以输入结束字符为条件的转到链接被连接到后缀根节点。因此,在图2a的示例中,具有node_id 11的节点将被创建,并且转到链接将从后缀根节点被延伸到该节点,该后缀根节点也以字符“$”为条件。同样,本技术不要求采用输入结束字符。因此,在不使用输入结束字符的情况下,可以省略步骤316和318。
[0055]
一旦词汇表中的所有词段都在特里结构中被表示,全弹出词元(例如,附图标记206a)和失效链接(例如,附图标记212)可以分别被计算并被添加到特里结构,如图3b和图3c的方法320和340所示。对此,如图3b的步骤322所示,根节点(具有node_id 0的节点)和后缀根节点(具有node_id 2的节点)都将被分配全弹出词元和空的(空)失效链接。
[0056]
在步骤324中,对于表示与词汇表中的词段相匹配的串的每个节点,该节点将被分配与其表示的词段相对应的全弹出词元或全弹出token_id,以及指向后缀根节点(具有
node_id 2的节点)的失效链接。因此,在图2a的示例中,因为词汇表200a包括词段“ab”,所以串“ab”的节点(具有node_id 4的节点)将获得“ab”的全弹出词元,以及指向“##”的节点(具有node_id 2的后缀根节点)的失效链接。同样,因为词汇表200a包括后缀词段“##c”,所以串“##c”的节点(具有node_id 9的节点)将获得“##c”的全弹出词元和指向“##”的节点的失效链接。
[0057]
如步骤326所示,对于表示不在词汇表中的串的任何节点,将根据图3c的方法340计算其(多个)全弹出词元和失效链接。对此,图3c描述了根据下面阐述的算法1的处理。在下面的算法1中,针对其计算(多个)全弹出词元和失效链接的节点由v标识,其父节点由u标识,并且将u连接到v的转到链接以字符c为条件。函数fail(x)返回具有node_id x的节点的失效链接的目标的node_id。因此,在图2a的示例中,fail(3)将返回2,因为具有node_id 3的节点具有指向具有node_id 2的节点的失效链接。函数goto(x,c)返回转到链接的目标的node_id,该转到链接从具有node_id x的节点延伸,并且以字符c为条件。如果具有node_id x的节点没有以c为条件的转到链接,则函数goto(x,c)的结果将为空。因此,在图2a的示例中,goto(3,“b”)将返回4,因为具有node_id 3的节点具有以指向具有node_id 4的节点的字符“b”为条件的转到链接。函数full_pops(x)返回具有node_id x的节点的全弹出词元。符号“!=”指示逻辑测试“不等于”。符号“==”指示逻辑测试“等于”。运算x=y指示变量x被分配值y。如下使用的运算“ ”指示值将被串接(例如,如果x是[a]并且y是[b],则x y将是[a,b])。while、if、else和运算都按照计算机编程领域中通常理解的方式运行。
[0058]
算法1:
[0059]
01行:full_pops(v)=full_pops(u)
[0060]
02行:w=fail(u)
[0061]
03行:while w!=null and goto(w,c)==null:
[0062]
04行:full_pops(v)=full_pops(v) full_pops(w)
[0063]
05行:w=fail(w)
[0064]
06行:if w!=null:
[0065]
07行:fail(v)=goto(w,c)
[0066]
08行:else:
[0067]
09行:fail(v)=0
[0068]
因此,根据上述算法1的01行,表示不在词汇表中的串的任何节点v最初将被分配与先前针对其父节点计算的全弹出词元相同的全弹出词元。该操作由图3c的步骤342表示。同样,根据算法1的02行,变量w最初将被分配与父节点u的失效链接相同的值。该操作由图3c的步骤344表示。因此,在图2a的示例中,如果v是node_id 5,u是node_id 4,并且c是字符“c”,那么full_pops(v)最初将被分配全弹出词元“ab”,因为这是先前已经根据步骤324针对其父节点u(具有node_id 4的节点)计算的全弹出词元。继续同一示例,变量w最初将被分配值“2”,因为父节点u(具有node_id 4的节点)具有指向具有node_id 2的节点的失效链接。
[0069]
根据算法1的第03-05行,while循环将开始,其每个循环以变量w不为空为条件,并且节点w不具有以字符c为条件的转到链接。这两个初始条件分别在图3c的步骤346和348中被表示。基于w的初始值为2,03行的第一条件(和步骤346)将被满足。然而,基于c是字符“c”,函数goto(2,“c”)将返回值9,因为具有node_id 2的节点具有以指向具有node_id 9的节点的“c”为条件的转到链接,因此不能满足03行的第二条件(以及步骤348)。因此,在本示例中,该过程将跳过04行和05行,并前进到06行。这在图3c中由连接步骤348和步骤354的“否”箭头表示。
[0070]
根据算法1的06行和07行,如果w不为空,那么fail(v)将被分配与goto(w,c)相同的值。这个条件和结果在图3c中由连接步骤354和步骤356的“是”箭头表示。因此,在本示例中,因为w仍然具有值“2”,并且因为具有node_id 2的节点具有以指向具有node_id 0的节点的字符“c”为条件的转到链接,所以节点v的失效链接将被分配值9,使得它也指向具有node_id 9的节点。因此,处理将终止,其中具有node_id 5的节点保持其最初分配的全弹出词元“ab”,其被分配指向具有node_id 9的节点的失效链接。
[0071]
另一方面,根据算法1的06、08和09行,如果w反而为空,那么fail(v)也将被分配空值(给定空的失效链接)。这个条件和结果在图3c中由连接步骤354和步骤358的“否”箭头表示。
[0072]
在刚刚描述的过程已经完成之后,可以针对每个下一节点重复该过程,利用针对每个先前节点计算的(多个)全弹出词元和失效链接。因此,在该过程在刚刚描述的示例中终止之后,u可以变成node_id 5,v可以变成node_id 7,使得c变成字符“z”。利用这些新的参数,根据算法1的01行(和步骤342),full_pops(v)最初将被分配一个全弹出词元“ab”,因为这是刚刚针对其父节点u(具有node_id 5的节点)计算的全弹出词元,如上所述。同样,根据算法1的02行(以及步骤344),变量w最初将被分配值“9”,因为节点u的失效链接(在上述前一轮处理中计算的)指向具有node_id 9的节点。基于w和c的这些值,w将不为空,并且goto(w,c)最初将为空,因为具有node_id 9的节点没有以字符“z”为条件的转到链接。这样,算法1的03行中的两个条件都将被满足,并且while循环将前进到04行。该条件和结果的集合在图3c中由将步骤346连接到步骤348的“是”箭头和将步骤348连接到步骤350的“是”箭头表示。
[0073]
根据算法1的04行,full_pops(v)的初始值将被增加full_pops(w)。该操作由图3c的步骤350表示。因为具有node_id 9的节点具有来自步骤324的先前计算的“##c”的全弹出词元,并且因为在步骤342中full_pops(v)最初被分配值“ab”,所以这些值被串接,使得full_pops(v)变成[“ab”,“##c”]。然后,在算法1的05行中,w被分配对应于具有node_id w的节点的失效链接的目标的新值。该操作由图3c的步骤352表示。因此,在本示例中,因为w具有值9,并且因为具有node_id9的节点具有指向具有node_id 2的节点的失效链接,所以在05行中w被重新分配值2。该过程然后将返回到03行,w具有新的值2。这由图3c中将步骤352连接回到步骤346的箭头表示。但是,在第二遍中,goto(2,“z”)将返回值10,因为具有node_id 2的节点具有以字符“z”为条件的转到链接,该链接指向具有node_id 10的节点。因此,goto(w,c)不会为空,并且while循环的条件(算法1的03行;图3c的步骤348)将在该第二遍时失效。因此,该过程将前进到算法1的06行,其中w仍然具有值2。因为w不为空,所以06行(步骤354)的条件将被满足,并且过程将前进到07行(步骤356),其中fail(v)将被分配与goto(w,c)相同的值。同样,因为goto(2,“z”)是10,所以节点v的失效链接将同样指向具有node_id 10的节点。因此,该处理将终止,其中具有node_id 7的节点具有[“ab”,“##c”]的全弹出词元和指向具有node_id10的节点的失效链接。
[0074]
图4是根据本公开的各方面的示例性方法的流程图。对此,图4表示示例性过程400,词元化器114可以跟随该过程来解析图2a和图2b所示类型的特里结构。因此,在步骤402,词元化器114将接收要被词元化的单词。然后,使用特里结构,词元化器114将确定根节点(例如,在图2a和图2b中,根节点是具有node_id 0的节点)是否具有对应于单词的第一字符的转到链接。例如,如果单词是如上所述的“abcz$”,则词元化器114将确定根节点是否具有对应于字母“a”的转到链接。
[0075]
如果根节点具有对应于单词的第一字符的转到链接,那么在步骤406中,词元化器114将跟随转到链接以到达下一节点。在步骤407中,词元化器114将检查该单词是否有更多的字符。如果是,在步骤408中,词元化器114将考虑该单词的下一(第二)字符。在步骤410中,词元化器114将确定所讨论的节点是否具有对应于单词的下一(第二)字符的转到链接。如果是,词元化器114将返回到步骤406,并跟随对应于第二字符的转到链接以到达另一节点。然后,在步骤407中,词元化器114将检查该单词是否具有任何其它的字符。如果是,词元化器114将在步骤408考虑下一(第三)字符,并返回到步骤410,以确定所讨论的节点是否具有对应于该单词的第三字符的转到链接。这个过程将针对每个下一字符和节点重复,直到到达这样一个节点,该节点被发现(在步骤410)不具有对应于所讨论的字符的转到链接,或者直到发现(在步骤407)该单词中没有其它的字符。
[0076]
每当词元化器114确定没有其它的字符要处理时(在步骤407),词元化器114将前进到步骤418,其中词元化器114将使用词汇表来标识对应于所收集的任何全弹出token_id的全弹出词元(对于图2a所示类型的特里结构,可以省略该步骤),然后该过程将在步骤420结束。
[0077]
每当词元化器114在步骤410确定所讨论的节点没有对应于所考虑的当前字符的转到链接时,它将前进到步骤412,其中它将收集该节点的(多个)全弹出词元或(多个)全弹出token_id。然后,在步骤414,词元化器114将确定所讨论的节点是否具有失效链接。如果节点没有失效链接(或者它的失效链接是空的),这意味着单词不能成功地被词元化。因此,词元化器114将前进到步骤422,其中它将把整个单词映射到单个词元,诸如“《unk》”,这指示该单词是未知的,并且然后该过程将在步骤424结束。然而,如果该节点确实具有失效链接,则词元化器114将跟随该失效链接以到达下一节点(如步骤416所示),并且然后返回到步骤410,以确定该新节点是否具有对应于被考虑的当前字符的转到链接。
[0078]
类似地,如果在步骤404发现根节点没有对应于单词的第一字符的转到链接,那么词元化器114也将前进到步骤412,其中它将从根节点(在图2a和图2b的示例中是空的)收集(多个)全弹出词元或(多个)全弹出token_id。然后,在步骤414中,词元化器114将确定根节点是否具有失效链接。这里同样,如果根节点没有失效链接(或者它的失效链接是空的),词元化器114将把整个单词映射到单个“未知”词元,诸如“《unk》”(步骤422),并且然后过程将结束(步骤424)。另一方面,如果根节点确实具有失效链接,则词元化器114将跟随失效链接以到达下一节点(如步骤416所示),并且然后前进到步骤410,以确定该新节点是否具有对应于单词的第一字符的转到链接。
[0079]
作为关于图2a、图2b和图4刚刚描述的解析的结果,词元化器114将只标识那些表示样本文本的最长前缀和每个下一最长后缀的全弹出词元。此外,由于每个节点具有预先计算的全弹出词元或代表性的全弹出token_id,所以图2a和图2b的特里结构能够在单遍中
被解析,而不需要回溯到先前的节点来收集任何全弹出词元或全弹出token_id。这样,对样本文本“abcz$”进行词元化仅需要解析特里结构一次,并跟随七个链接(五个转到链接和两个失效链接)以便标识词段“ab”、“##c”和“##z”。然而,对于图2a和图2b所示类型的树结构,预计算每个节点的全弹出词元或全弹出token_id导致重复,这能够影响生成(或初始化)特里结构201a所花费的时间以及存储它所需的空间。因此,在期望更短的初始化时间和/或更小的特里结构201a的情况下,可以考虑图5a和图5b的示例。
[0080]
图5a还描绘了根据本技术的各方面的示例性词汇表和对应的特里结构。在图5a的示例中,词汇表500a具有与图2a的词汇表200a相同的组成和内容,因此包含相同的六个词段:a、ab、abcd、abczd、##c和##z。同样,在图5a的示例中,词汇200a也被转换成特里结构501a。
[0081]
如同前面的示例,虽然特里结构501a可以被提现为适合于由词元化器114处理的任何数据结构,但是为了便于解释,它在图5a中被图示。对此,图5a中的每个圆圈(例如,附图标记502)表示特里结构501a中的节点。每个圆形节点在其顶部具有一个数字(例如,附图标记504),这是该节点的node_id。另外,对于将具有与其前一节点不同的匹配词段集合的每个节点,在圆圈的底部将有带括号的自弹出词元(例如,附图标记506a)。对此,在节点表示直接匹配词汇表500a中的词段的串的情况下,在图2a和图5a的特里结构之间将没有差别,并且该节点将因此具有与特里结构201a中所示的全弹出词元相同的自弹出词元(例如,具有node_id 3、4、6、8、9、10的节点)。在特里结构201a中的节点的全弹出词元为空(“[]”)的情况下,其在特里结构501a中的自弹出词元也将为空(“[]”)(例如,具有node_id0、1、2、11、12的节点)。在特里结构201a中的节点的全弹出词元将与前一节点的全弹出词元相同的情况下,其在特里结构501a中的自弹出词元将为空(“[]”)(例如,具有node_id 5的节点),从而避免该串在数据结构中的重复。最后,在特里结构201a中的节点的全弹出词元将包括前一节点的全弹出词元中的词段以及附加词段的情况下,其在特里结构501a中的自弹出词元将仅列出附加词段(例如,具有node_id 7的节点)。
[0082]
如图2a的情况,特里结构501a的图5a的实线箭头(例如,附图标记508)表示转到链接,并且每个箭头(例如,附图标记510)旁边的字符表示跟随该转到链接的条件。同样,特里结构501a的图5a的虚线箭头(例如,附图标记512)表示失效链接,其以与上面参考图2a描述的方式相同的方式操作。然而,在图5a的示例中,特里结构501a另外包括表示prev_match链接的虚线箭头(例如,附图标记518)。对于表示词汇表500a中词段的任何节点(例如,具有node_id 4的节点),prev_match链接将为空,因为该节点已经表示词汇表500a中可用的最长匹配。这个空的prev_match链接在图5a中由指回矩形“空”框(例如,利用附图标记514、520标识的框)的prev_match箭头图示地示出。对于其在特里结构201a中的(多个)全弹出词元与前一节点的(多个)全弹出词元相同的任何节点,它将反而具有指回具有相同(多个)全弹出词元的最早祖先节点的prev_match链接。例如,因为具有node_id 5的节点否则将需要“ab”的全弹出词元,所以它具有指回具有node_id 4的节点的prev_match链接518,该节点的自弹出词元是“ab”。如已经提到的,这避免了在节点5中重复“ab”,因此可以减少初始化时间和特里结构的大小。对于其在特里结构201a中的全弹出词元将包括前一节点的(多个)全弹出词元中的(多个)词段以及一个或多个附加词段的任何节点,它将具有指回具有那些共享词段的最早祖先节点的prev_match链接。例如,因为具有node_id 7的节点否则将需要
[“ab”,“##c”]的全弹出词元,所以它具有一个列出附加词段的自弹出词元(“##c”)和一个指回具有node_id 4的节点的prev_match链接,该节点的自弹出词元是“ab”。
[0083]
因此,使用示例特里结构501a,假设处理系统102的词元化器114正尝试对“abcz$”进行词元化,它将再次从具有node_id 0的根节点开始。基于“abcz$”的第一字符是“a”,词元化器114将跟随转到链接508以到达具有node_id 3的节点。然后,由于“abcz$”的第二字符是“b”,词元化器114将跟随“b”的转到链接以到达具有node_id4的节点。同样,由于“abcz$”的第三字符是“c”,词元化器114将跟随“c”的转到链接以到达具有node_id 5的节点。类似地,由于“abcz$”的第四字符是“z”,词元化器114将跟随“z”的转到链接以到达具有node_id 7的节点。
[0084]
然而,由于“abcz$”的第五字符不是“d”,词元化器114将不会跟随下一转到链接到具有node_id 8的节点。相反,词元化器114将收集它未能继续前进的节点(具有node_id 7的节点)的预先计算的自弹出词元(“##c”),并且还将递归地跟随从该节点延伸的prev_match链接的链,并收集该链中每个节点的(多个)自弹出词元,直到遇到空的prev_match链接。因此,由于具有node_id 7的节点具有指向具有node_id 4的节点的prev_match链接,词元化器114也将收集该节点的具有node_id 4的节点的自弹出词元(“ab”)。词元化器114然后将尝试跟随node_id 4的节点的prev_match链接。然而,因为具有node_id 4的节点的prev_match链接是空的(在图5a中显示为指向“空”框520的箭头),所以将不再有要收集的自弹出词元。词元化器114随后将串接所收集的自弹出词元,以生成自弹出词元的阵列([“ab”、“##c”]),然后将跟随失效链接512以到达具有node_id 10的节点。因为词元化器114仅跟随prev_match链接,并且当它不能使用转到链接到达下一节点时串接自弹出词元,所以串接的词元自动表示匹配词汇表500a中已知词段的样本文本的最长片段。因此,在该示例中,词汇表500a中的“abcz$”内的最长前缀被表示为“ab”,紧跟“ab”的最长后缀被标识为“##c”。
[0085]
继续同一示例,在跟随失效链接512到具有node_id 10的节点之后,词元化器114将尝试跟随下一转到链接。然而,由于具有node_id10的节点没有其它的转到链接,词元化器114将被迫再次收集该节点的自弹出词元(“##z”)。在这种情况下,由于节点的prev_match链接是空的(在图5a中显示为指向“空”框514的箭头),将没有附加自弹出词元要收集。因此,收集的具有node_id 10的节点的自弹出词元然后将与先前收集的自弹出词元串接,以生成三个自弹出词元(“ab”、“##c”、“##z”)的阵列。词元化器114然后将跟随失效链接以到达具有node_id 2的节点。
[0086]
一旦在具有node_id 2的节点,词元化器114将试图找到“abcz$”的第五字符“$”的转到链接。由于特里结构501a被配置有专用于输入结束字符“$”的转到链接,词元化器114将跟随该链接到具有node_id11的节点。由于在“abcz$”中没有其它的字符要处理,词元化器114将停止解析特里结构501a。因此,该过程将以现有的三个全弹出词元(“ab”、“##c”、“##z”)的阵列结束。
[0087]
图5b还描绘了根据本技术的各方面的示例性词汇表和对应的特里结构。在图5b的示例中,词汇表500b与图5a的词汇表500a相同,除了词汇表500b中的每个单词还与对应的token_id相关联。例如,词汇表200b中的第一词段“a”与token_id“1”相关联。同样,图5b的特里结构500b与图5a的特里结构500a相同,并且将以相同的方式构造,除了特里结构500b
包含数字自弹出token_id(例如,附图标记206b)而不是每个自弹出词元的文本。在图5b的示例中,自弹出token_id能够结合词汇表500b使用,以确定相关联的自弹出词元的文本。除了刚刚描述的差异,图5a和图5b的特里结构是相同的,并且两个图之间所有共同的附图标记标识相同的特征。因此,词元化器114将以与以上关于图5a的特里结构501a所描述的相同方式解析图5b的特里结构501b,但是代替收集每个自弹出词元的文本,它将收集数字数字的自弹出token_id。因此,在图5b的示例中,在词元化器114到达具有node_id 11的节点并且没有更多字符要处理之后,它将停止解析特里结构501b,并且然后使用收集的自弹出token_id(2、5、6)来标识相应的词元(ab、##c、##z)。
[0088]
图5a和图5b的特里结构的节点和转到链接能够使用上面参考图3a描述的相同过程来创建。图6a至图6c是为图4a和图4b的示例中所示类型的特里结构构建自弹出词元或自弹出token_id、prev_match链接和失效链接的示例性方法的流程图。对此,如图6a的步骤602所示,根节点(具有node_id 0的节点)和后缀根节点(具有node_id 2的节点)将被分配自弹出词元、prev_match链接和空的(空)失效链接。
[0089]
在步骤604中,对于表示与词汇表中的词段匹配的串的每个节点,该节点将被分配一个对应于它表示的词段的自弹出词元或自弹出token_id,一个空的(空)prev_match链接,以及一个指向后缀根节点(具有node_id 2的节点)的失效链接。因此,在图5a的示例中,因为词汇表500a包括词段“ab”,所以字符串“ab”的节点(具有node_id4的节点)将获得自弹出词元“ab”、空的prev_match链接(在图5a中利用指向“空”框520的虚线箭头图示)以及指向“##”的节点(具有node_id 2的后缀根节点)的失效链接。同样,因为词汇表500a包括后缀词段“##c”,所以串“##c”的节点(具有node_id 9的节点)将获得“##c”的自弹出词元、空的prev_match链接(在图5a中利用指向“空”框514的虚线箭头示出),以及指回“##”的节点的失效链接。
[0090]
如步骤606所示,对于表示不在词汇表中的串的任何节点,将根据图6b的方法620(其结合了图6c的方法640)计算其(多个)自弹出词元、prev_match链接和失效链接。对此,图6b描述了根据下面阐述的算法2的处理。在下面的算法2中,正在针对其计算(多个)自弹出词元、prev_match链接和失效链接的节点由v表示,其父节点由u表示,并且将u连接到v的转到链接以字符c为条件。在算法2中,函数self_pops(x)返回具有node_id x的节点的(多个)自弹出词元。函数prev_match(x)返回具有node_id x的节点的prev_match链接的目标的node_id。因此,在图5a的示例中,prev_match(5)将返回4,因为具有node_id 5的节点具有指向具有node_id 4的节点的prev_match链接。操作x.append(y)将y附加到阵列(或列表)x。例如,如果x是列表[0,1,2],并且y具有值5,则x.append(y)将返回列表[0,1,2,5]。操作reverse(x)将阵列x的元素反向。例如,如果x是列表[0,1,2],那么reverse(x)会将x改变成列表[2,1,0]。for n in x操作:对列表x中的每个连续元素n执行冒号后面的任何操作。当第一函数调用第二函数时,第二函数中的操作return x将导致x被传递回第一函数。函数fail(x)和goto(x,c)以与上述算法1相同的方式运行。同样,符号“!=”和“==”以及“=”和“ ”表示与以上关于算法1所描述的相同的操作。最后,如上所述,while、if、else和运算都按照计算机编程领域中通常理解的方式运行。
[0091]
算法2:
[0092]
01行:self_pops(v)=null
[0093]
02行:if self_pops(u)!=null:
[0094]
03行:prev_match(v)=u
[0095]
04行:else:
[0096]
05行:prev_match(v)=prev_match(u)
[0097]
06行:w=fail(u)
[0098]
07行:while w!=null and goto(w,c)==null:
[0099]
08行:self_pops(v)=self_pops(v) recursive_pops(w)
[0100]
09行:w=fail(w)
[0101]
10行:if w!=null:
[0102]
11行:fail(v)=goto(w,c)
[0103]
12行:else:
[0104]
13行:fail(v)=0
[0105]
函数recursive_pops(x):
[0106]
14行:prev_match_chain=[]
[0107]
15行:while x!=null:
[0108]
16行:prev_match_chain.append(x)
[0109]
17行:x=prev_match(x)
[0110]
18行:pops_list=[]
[0111]
19行:for n in reverse(prev_match_chain):
[0112]
20行:pops_list=pops_list self_pops(n)
[0113]
21行:return pops_list
[0114]
因此,根据上述算法2的01行,表示不在词汇表中的串的任何节点v最初将被分配空的自弹出词元。该操作由图6b的步骤622表示。
[0115]
接下来,根据算法2的02和03行,如果父节点u的自弹出词元不为空,则节点v将被分配指向父节点u的prev_match链接。这个条件和结果在图6b中由将步骤624连接到步骤626的“是”箭头表示。因此,在图5a的示例中,如果v是node_id 5,u是node_id 4,并且c是字符“c”,则prev_match(v)将被分配值4,因为具有node_id 4的节点具有自弹出词元“ab”。
[0116]
另一方面,根据算法2的02、04和05行,如果父节点u具有空的自弹出词元,则节点v将被分配指向节点u的prev_match链接的目标的prev_match链接。这个条件和结果在图6b中由将步骤624连接到步骤628的“否”箭头表示。
[0117]
接下来,根据算法2的06行,变量w最初将被分配与父节点u的失效链接相同的值。该操作由图6b的步骤630表示。因此,继续基于图5a的相同示例,其中v是node_id 5,u是node_id 4,c是字符“c”,那么变量w最初将被分配值“2”,因为父节点u(具有node_id4的节点)具有指向具有node_id 2的节点的失效链接。
[0118]
根据算法2的07-09行,while循环将开始,其每个循环以变量w不为空并且节点w不具有以字符c为条件的转到链接为条件。这两个初始条件分别在图6b的步骤632和634中表示。基于w的初始值为2,07行的第一条件(以及步骤632)将被满足。然而,基于c是字符“c”,函数goto(2,“c”)将返回值9,因为具有node_id 2的节点具有以指向具有node_id 9的节点的“c”为条件的转到链接,因此无法满足07行的第二条件(以及步骤634)。因此,在本示例
中,该过程将跳过08行和09行,并前进到10行。这在图6b中由连接步骤634到步骤652的“否”箭头表示。
[0119]
根据算法2的10行和11行,如果w不为空,那么fail(v)将被分配与goto(w,c)相同的值。这个条件和结果在图6b中由将步骤652连接到步骤654的“是”箭头表示。因此,在本示例中,因为w仍然具有值“2”,并且因为具有node_id 2的节点具有以指向具有node_id 0的节点的字符“c”为条件的转到链接,所以节点v的失效链接将被分配值9,使得它也指向具有node_id 9的节点。因此,处理将终止,其中具有node_id 5的节点保持其最初分配的空的自弹出词元,并被分配指回其具有node_id 4的父节点的prev_match链接,以及指向具有node_id 9的节点的失效链接。
[0120]
另一方面,根据算法2的10、12和13行,如果w反而为空,那么fail(v)也将被分配空值(给定空的失效链接)。这个条件和结果在图6b中由将步骤652连接到步骤656的“否”箭头表示。
[0121]
在刚刚描述的过程已经完成之后,可以利用为每个先前节点计算的(多个)自弹出词元、prev_match链接和失效链接,针对每个下一节点重复该过程。因此,在该过程在刚刚描述的示例中终止之后,u可以变成node_id 5,v可以变成node_id 7,使得c变成字符“z”。利用这些新的参数,根据算法2的第01行(以及步骤622),self_pops(v)最初将被分配空的自弹出词元。
[0122]
接下来,根据算法2的02行(以及步骤624),该条件将不被满足,因为父节点u(具有node_id 5的节点)具有空的自弹出词元(如上所述,在前一轮处理中计算的)。因此,该过程将跳过算法2的03行,反而前进(经由04行)到05行(步骤628)。根据05行,因为节点u具有指向具有node_id 4的节点的prev_match链接,所以prev_match(v)也将被分配值4。
[0123]
继续同一示例,根据算法2的06行(以及步骤630),变量w最初将被分配值“9”,因为节点u的失效链接(在上述前一轮处理中计算的)指向具有node_id 9的节点。然后,基于w和c的这些值,w将不为空,并且goto(w,c)最初将为空,因为具有node_id 9的节点没有以字符“z”为条件的转到链接。这样,算法2的07行中的两个条件都将被满足,并且while循环将前进到08行。该条件和结果的集合在图6b中由将步骤632连接到步骤634的“是”箭头和将步骤634连接到步骤636的“是”箭头表示。
[0124]
根据算法2的08行,self_pops(v)的初始值将被增加由recursive_pops(w)函数返回的值。该操作由图6b的步骤636表示。在算法2的14-21行和图6c中定义了recursive_pops(x)函数。当recursive_pops函数被调用时,它将通过利用无内容初始化名为prev_match_chain的阵列根据14行开始。该操作由图6c的步骤641表示。接下来,根据算法2的15-17行,while循环将开始。根据算法2的15行,while循环的每个循环都以变量x不为空为条件。该条件由图6c的步骤642表示。
[0125]
对此,如果已经传递给recursive_pops函数的值x不为空,则根据算法2的16行,该值将被附加到prev_match_chain阵列。这个条件和结果在图6c中由将步骤642连接到步骤643的“是”箭头表示。因此,在本示例中,因为w被传递到recursive_pops函数中,并且因为w具有值9,所以变量x在第一编时将具有值9,并且15行的条件将被满足。因此,值9将被附加到prev_match_chain阵列,使其成为单条目列表[9]。然后,根据算法2的17行,x被分配对应于它自己的prev_match链接的目标的新值。该操作由图6c的步骤644表示。在本示例中,因
为具有node_id 9的节点具有空的prev_match链接(根据步骤604设置),所以x将在算法2的17行被重新分配空值。然后,该过程将返回到15行。这由图6c中将步骤644连接回到步骤642的箭头表示。然而,在该第二遍时,由于x现在为空,所以15行的条件将不被满足,并且过程将前进到算法2的18行。该条件和结果在图6c中由将步骤642连接到步骤645的“否”箭头表示。
[0126]
根据算法2的18行,名为pops_list的新阵列将利用无内容被初始化。该操作由图6c的步骤645表示。然后,根据算法2的19和20行,for循环将被发起,其中prev_match_chain阵列将被反向,并且该反向列表的每个元素n的(多个)自弹出词元将被连续收集并添加到pops_list阵列中。该操作由图6c的步骤646表示。在本示例中,因为prev_match_chain是单条目列表[9],并且因为具有node_id的节点具有自弹出词元“##c”,所以for循环将以pops_list被设置为单条目列表[“##c”]而终止。
[0127]
根据算法2的21行,一旦for循环已经完成,pops_list的内容将作为对算法2的08行中recursive_pops(w)的响应被返回。该操作由图6c的步骤647表示,并且结果值将被用于完成由图6b的步骤636表示的操作。因此,在本示例中,因为self_pops(v)在算法2的01行(以及图6b的步骤622)中被设置为空,所以08行(以及图6b的步骤636)将导致self_pops(v)被设置为[“##c”]。
[0128]
然后,在算法2的09行中,w被分配对应于具有node_id w的节点的失效链接的目标的新值。该操作由图6b的步骤650表示。因此,在本示例中,因为w具有值9,并且因为具有node_id 9的节点具有指向具有node_id 2的节点的失效链接,所以在09行中w被重新分配值2。该过程然后将返回到07行,w具有新的值2。这由图6b中将步骤650连接回到步骤632的箭头表示。但是,在第二遍时,goto(2,“z”)将返回值10,因为具有node_id 2的节点具有以字符“z”为条件的转到链接,该链接指向具有node_id 10的节点。因此,goto(w,c)将不为空,while循环的条件(算法2的07行;图6b的步骤634)将在该第二遍时失效。因此,该过程将前进到算法2的10行,其中w仍然具有值2。因为w不为空,所以10行的条件(步骤652)将被满足,并且该过程将前进到11行(步骤654),其中fail(v)将被分配与goto(w,c)相同的值。同样,因为goto(2,“z”)是10,所以节点v的失效链接将同样指向具有node_id 10的节点。因此,处理将终止,其中具有node_id 7的节点被分配“##c”的自弹出词元,prev_match链接指回具有node_id 4的节点,并且失效链接指向具有node_id 10的节点。
[0129]
图7是根据本公开的方面的示例性方法的流程图。对此,图7表示示例性过程700,词元化器114可以跟随该过程来解析图5a和图5b所示类型的特里结构。因此,在步骤702,词元化器114将接收要被词元化的单词。然后,使用特里结构,词元化器114将确定根节点(例如,在图5a和图5b中,根节点是具有node_id 0的节点)是否具有对应于单词的第一字符的转到链接。例如,如果如上所述单词是“abcz$”,词元化器114将确定根节点是否具有对应于字母“a”的转到链接。
[0130]
如果根节点具有对应于单词的第一字符的转到链接,那么在步骤706中,词元化器114将跟随转到链接以到达下一节点。在步骤707中,词元化器114将检查该单词是否有更多的字符。如果是,在步骤708中,词元化器114将考虑单词的下一(第二)字符。在步骤710中,词元化器114将确定所讨论的节点是否具有对应于单词的下一(第二)字符的转到链接。如果是,词元化器114将返回到步骤706,并跟随对应于第二字符的转到链接以到达另一节点。
然后,在步骤707中,词元化器114将检查该单词是否具有任何其它的字符。如果是,词元化器114将在步骤708考虑下一(第三)字符,并返回到步骤710,以确定所讨论的节点是否具有对应于该单词的第三字符的转到链接。这个过程将针对每个下一字符和节点重复,直到到达这样一个节点,该节点被发现(在步骤710)不具有对应于所讨论的字符的转到链接,或者直到发现(在步骤707)该单词中没有其它的字符。
[0131]
每当词元化器114确定没有其它的字符要处理时(在步骤707),词元化器114将前进到步骤718,其中词元化器114将使用词汇表来标识对应于被收集的任何全弹出token_id的全弹出词元(对于图5a所示类型的特里结构,可以省略该步骤),并且然后该过程将在步骤720结束。
[0132]
每当词元化器114在步骤710确定所讨论的节点不具有对应于所考虑的当前字符的转到链接时,它将前进到步骤712,其中它将收集该节点的(多个)自弹出词元或自弹出token_id。然后,在步骤713,词元化器114也将递归地跟随从该节点延伸的prev_match链接的链,并收集该链中每个节点的(多个)自弹出词元或(多个)自弹出token_id,直到遇到空的prev_match链接。如上所述,在步骤712和713中收集的(多个)自弹出词元或(多个)自弹出token_id将被串接。
[0133]
在步骤714,词元化器114将确定所讨论的节点是否具有失效链接。如果节点没有失效链接(或者它的失效链接是空的),这意味着单词不能被成功地词元化。因此,词元化器114将前进到步骤722,其中它将把整个单词映射到单个词元,诸如“《unk》”,这表示该单词是未知的,并且然后该过程将在步骤724结束。然而,如果该节点确实具有失效链接,则词元化器114将跟随失效链接以到达下一节点(如步骤716所示),并且然后返回到步骤710,以确定该新节点是否具有对应于正在考虑的当前字符的转到链接。
[0134]
类似地,如果在步骤704发现根节点不具有对应于单词的第一字符的转到链接,则词元化器114也将前进到步骤712,其中它将从根节点(在图5a和图5b的示例中是空的)收集(多个)自弹出词元或(多个)自弹出token_id。然后,在步骤714中,词元化器114将确定根节点是否具有失效链接。这里同样,如果根节点没有失效链接(或者它的失效链接是空的),词元化器114将把整个单词映射到单个“未知”词元,诸如“《unk》”(步骤722),并且然后过程将结束(步骤724)。另一方面,如果根节点确实具有失效链接,则词元化器114将跟随失效链接以到达下一节点(如步骤716所示),并且然后前进到步骤710,以确定该新节点是否具有对应于单词的第一字符的转到链接。
[0135]
作为参考图5a、图5b和图7刚刚描述的解析的结果,词元化器114将仅标识表示样本文本的最长前缀和每个下一最长后缀的那些自弹出词元。此外,借助于预先计算的prev_match链接以及预先计算的自弹出词元或代表性的自弹出token_id,图5a和图5b的特里结构仍然可以在单遍中被解析,但是不需要如图2a和图2b的特里结构中的全弹出词元或全弹出token_id的复制。因此,对样本文本“abcz$”进行词元化只需要解析特里结构一次,并跟随八个链接(五个转到链接、两个失效链接和一个prev_match链接)以便标识词段“ab”、“c##”和“##z”。
[0136]
尽管上面参考图2至图7描述的示例是在从左到右最长匹配优先的贪婪过程(或“正向最大匹配”过程)上操作的,但是通过将词汇表中的所有串反向并构造相应的特里结构,相同的过程能够适用于从右到左最长匹配优先的贪婪过程(或“反向最大匹配”过程)。
[0137]
同样,尽管以上参考图2至图7描述的示例标识了对应于给定单词的每个字符的词段,但在本技术的一些方面,词元化器可以被配置成跳过未知的或在词汇表中找不到的字符,并继续处理。例如,词元化器114可以被配置为将任何未识别的字符的占位符“《unk》”词元插入到全弹出列表中,然后如已经描述的那样继续处理下一字符。因此,使用上面表1的示例的词汇表,如果字符“~”是未知的,则词元化器114可以被配置成将单词“un~knowable”映射到[un,《unk》,##know,#able]。
[0138]
除非另有说明,否则前述替代示例并不相互排斥,而是可以以各种组合来实现,以实现独特的优点。由于在不脱离权利要求所定义的主题的情况下,可以利用上述特征的这些和其他变型和组合,因此示例性系统和方法的前述描述应当被视为说明性的,而不是对权利要求所定义的主题的限制。此外,本文中描述的示例的提供,以及措辞为“诸如”、“包括”、“包含”等的条款,不应该被解释为将权利要求的主题限制到特定的示例;相反,这些示例旨在仅图示许多可能实施例中的一些。此外,不同附图中的相同附图标记能够标识相同或相似的元件。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献