6

我发现Stanford POS Tagger相当不错,但不知何故我发现自己需要创建自己的 POS 标记器。

在过去的两周里,我到处闲逛,是否从解析树开始,或者一旦我们有了一个 pos 标记器就可以解析树,使用丑陋的 CFG 和 NFA,以便它们可以帮助我创建一个 POS 标记器什么不是。

我在这里结束这个问题,询问前辈,从哪里开始 POS 标记。(选择的语言是 Python,但 C 和 JAVA 不会受到伤害)。

4

1 回答 1

17

这取决于你的最终目标是什么。

如果目标是执行语法分析,即确定主语、谓词、它的参数、它的修饰符等,然后甚至可能执行语义分析,那么你不应该担心词性标注器。相反,您应该首先查看用于句法分析的各种方法 - 特别是基于短语结构的方法、概率方法和有限状态方法 - 并确定您想要使用的工具。该决定将取决于您的速度和准确性要求,您将有多少时间进行长期改进和维护,以及其他因素。一旦您为此决定了正确的工具(或实施策略),您可能最终不再需要标记器。原因是许多语法分析策略从根本上不需要标注器:它们只执行字典查找,它为每个单词返回,一个或多个可能的 POS 标签;消歧(即决定哪些标签实际上是正确的)由语法分析器隐式执行。一些语法分析器可能希望您在查找字典后应用 POS 标记器,但它们也会告诉您使用哪一个,因此您的问题的答案会很自然地遵循。

另一方面,如果您的目标不需要完整的语法分析,而只需要词性标记,我建议您在决定自己制作之前先查看现有的替代方案。可能的选择包括但不限于:

哪一个适合您的需求取决于许多因素,不一定按此优先顺序:

  1. 不透明性:您是否打算进行更正以改进结果,可能通过维护例外列表和更正后规则,可能在很长一段时间内?在这种情况下,您可能需要一个标记器,它不仅是开源的,而且使用一种方法,可以手动修改它使用的消歧策略。这在基于规则或 TBL 的标注器(如 Brill 标注器)中更容易,在某种程度上基于决策树学习的标注器(如 TreeTagger);在基于 Hidden-Markov-Model (HMM) 的标注器和基于条件随机场 (CRF) 的标注器(例如 Mallet Simple Tagger)中,它更加困难并且可能性更加有限,并且非常困难(纯后校正例外除外列表)在基于神经网络(如 SENNA)的标记器中。

  2. 目标语言:您是否只需要英语或其他语言?TreeTagger 对许多欧洲语言提供了开箱即用的支持,但上面列表中的其他语言不支持。添加对语言的支持总是需要字典,通常需要带注释的训练语料库(这可能很昂贵),并且有时需要您编写或修改数百个初始规则(例如,如果 Brill-tagger 方法是用过的)。

  3. 框架和编程语言: Mallet 和 Stanford 用于 Java,TreeTagger 是 C 语言(但不是开源的;有 Python 和 Java 包装器,但它们可能会导致显着减速和其他问题(‡)),SENNA 是在 C 和开源中,ANNIE 是在 Java 中并为 GATE 框架制作的,等等。这些标记器所需的环境存在差异,将它们移出自然栖息地可能会很痛苦。NLTK (Python) 对其中一些有包装器,但它们通常不涉及将源代码实际嵌入到 Python 中;相反,他们只是对您要标记的每条文本执行系统调用。这具有严重的性能影响。

  4. 速度:如果你每秒只处理几句话,任何标注器都可以处理。但是,如果您正在处理 TB 级数据或需要应对使用中的极端峰值,则需要执行正确类型的压力测试作为评估和决策的一部分。我从个人经验中知道,TreeTagger 和 SENNA 非常快,Stanford 比较慢,而 NLTK-wrappers 通常要慢几个数量级。无论如何,您需要进行测试。请注意,POS 标记可以通过将输入划分为多个分区并并行运行多个标记过程以直接的方式进行并行化。内存占用通常不是标记器本身的问题(但如果标记器是完全加载到内存中的通用 NLP 框架的一部分,则可能会出现问题)。

最后,如果现有的标注器都不能满足您的需求,而您真的决定创建自己的标注器,您仍然需要做出与上述类似的决定:正确的方法取决于准确性、速度、维护和多语言相关因素。POS 标记的主要方法在上面的示例列表中得到了很好的体现,即 Rule/TBL-style (Brill)、HMM/CRF (Mallet)、entropy-based (Stanford)、决策树学习 (TreeTagger)、神经网络(SENNA)。即使您决定自己制作,最好研究一些现有的,以了解它们的运作方式以及问题所在。

作为多语言的最后一句话:像上面这样的经典 POS 标记器要求您在应用标记器之前对输入进行标记(或者它们隐式地执行简单的标记化)。这不适用于无法使用标点符号和空格作为标记边界的语言,即中文、日文、泰文,在某种程度上是韩文和其他一些语言。对于这些,您需要使用专门的分词器,这些分词器通常在一个步骤中执行分词POS 标记。


(‡)我不了解Java 包装器,但我上次检查时(大约 1 年前) Python 包装器有几个问题:它只适用于 Python 2,它以相当复杂的方式使用系统调用,这是确保 Tree Tagger 在处理每个输入后刷新其缓冲区所必需的。后者有两个后果:处理速度比直接使用 Tree Tagger 时要慢,并且某些语言不能使用完整的命令行工具管道,因为缓冲区刷新太复杂了。

于 2013-04-13T01:24:19.987 回答