我发现Stanford POS Tagger非常好,但不知怎的,我发现自己需要创建自己的POS标记器。
在过去的两周里,我在这里和那里漫步,关于是否从解析树开始,或者一旦我们有一个pos标记器,我们可以解析树,使用丑陋的CFG和NFA,这样他们就可以帮助我创建一个POS标记器,什么不是。
我在这里结束这个问题,询问老年人,从哪里开始进行POS标记。 (选择的语言是Python,但C和JAVA不会受到伤害)。
答案 0 :(得分:16)
这取决于你的最终目标。
如果目标是执行语法分析,即确定主语,谓词,其参数,修饰符等,然后甚至可能执行语义分析,那么你不应该担心POS标签。相反,您应首先查看语法分析的各种方法 - 特别是基于短语结构的方法,概率方法和有限状态方法 - 并确定您想要使用的工具。决定取决于您的速度和准确度要求,长期改进和维护的时间以及其他因素。一旦您确定了正确的工具(或实施策略),您可能最终不再需要标记器了。原因是许多语法分析策略从根本上不需要标记器:它们只执行字典查找,为每个单词返回一个或多个可能的POS标记;消歧(即决定哪些标签实际上是正确的)由语法分析器隐式执行。 一些语法分析器可能希望您在字典查找后应用POS标记器,但它们也会告诉您使用哪一个,因此您的问题的答案将非常自然地进行。
另一方面,如果您的目标不需要完整的语法分析,而只需要词性标注,我建议您首先查看现有的在决定制作自己的选择之前的替代方案。可能的选择包括但不限于:
哪一个适合您的需求取决于许多因素,不一定在此优先顺序中:
不透明度:您是否打算进行更正以改善结果,可能是通过长时间维护例外列表和更正后规则?在这种情况下,您可能需要一个不仅是开源的标记器,而且还使用一种方法,可以手动修改它使用的消歧策略。在基于规则或TBL标记器(例如Brill标记器)中,以及在某种程度上基于决策树学习的标记器(例如TreeTagger),这更容易;基于隐马尔可夫模型(HMM)标记器和基于条件随机场(CRF)的标记器(如Mallet Simple Tagger)更加困难和可能性更加有限,并且非常困难(除了纯后校正异常)列表)基于神经网络的标记器(如SENNA)。
目标语言:您是否只需要英语或其他语言? TreeTagger为许多欧洲语言提供了开箱即用的支持,但上面列表中的其他语言并不是。添加对语言的支持总是需要字典,它通常需要带注释的训练语料库(可能很昂贵),有时需要你编写或修改几百个初始规则(例如,如果Brill-tagger方法是使用)。
框架和编程语言:Mallet和Stanford用于Java,TreeTagger在C语言中(但不是开源的;有Python和Java包装器,但它们可能会导致显着的缓慢-down并有其他问题(‡)),SENNA在C和开源,ANNIE是Java并为GATE框架制作,依此类推。这些标记者需要的环境存在差异,将它们移出自然栖息地可能会很痛苦。 NLTK(Python)有一些包装器,但它们通常不涉及将源实际嵌入到Python中;相反,他们只是为您要标记的每段文本执行系统调用。这会产生严重的性能影响。
速度:如果您每秒只处理几句话,任何标记器都能够处理。但是,如果您正在处理数TB的数据或需要应对使用中的极端高峰,您需要执行正确的压力测试作为评估和决策的一部分。我从个人经验中知道,TreeTagger和SENNA非常快,斯坦福的速度相当慢,而NLTK包装器的速度通常要慢几个数量级。无论如何,你需要测试。请注意,通过将输入划分为多个分区并并行运行多个标记过程,可以直接对POS标记进行并行处理。内存占用通常不是标记器本身的问题(但如果标记器是完全加载到内存中的通用NLP框架的一部分,则可能是这样。)
最后,如果现有的标记符都没有满足您的需求并且您真的决定创建自己的标记器,那么您仍然需要做出类似于上述的决定:正确的方法取决于准确性,速度,维护和多语言相关的因素。上述示例列表很好地表示了POS标记的主要方法,即规则/ TBL样式(Brill),HMM / CRF(Mallet),基于熵(Stanford),决策树学习(TreeTagger),神经网络(SENNA)。即使您决定自己制作,也应该研究一些现有的,以了解它们的运作方式和问题所在。
作为多语言的最后评论:如上所述的经典POS标记器要求您在应用标记器之前对输入进行标记(或者它们隐式执行简单的标记化)。这不能使用标点符号和白色空间作为标记边界来标记的语言,即中文,日文,泰文,某种程度上是韩文和其他一些语言。对于那些,您需要使用专门的标记化器,并且这些标记器通常一步执行标记化和 POS标记。
(‡)我不知道Java wrapper,但Python wrapper上次检查时遇到了几个问题(大约1年前) :它只适用于Python 2,它以相当复杂的方式使用系统调用,这是确保Tree Tagger在处理完每个输入后刷新其缓冲区所必需的。后者有两个结果:处理速度比直接使用Tree Tagger时要慢,而且某些语言不能使用完整的命令行工具管道,因为缓冲区刷新过于复杂。