我正在使用Stanford Parser处理一大块文本。当解析器遇到无法解析的句子时,它会终止并给出以下运行时错误。有没有办法让Stanford Parser忽略错误,继续解析下一句?
一种方法是将文本分解成许多单句文档,然后解析每个文档并记录输出。然而,这需要多次加载Stanford Parser(每次解析文档时,都需要重新加载Stanford Parser)。加载解析器需要很多时间,但解析本身所需的时间要短得多。如果能找到一种方法避免每次句子都重新加载解析器就好了。
另一种解决方案可能是当解析器遇到错误时重新加载它,从停止的地方继续解析文本。有人知道如何实现这个解决方案吗?
最后但同样重要的是,是否存在任何Java包装器,可以忽略错误并保持Java程序运行,直到程序自然终止?
谢谢!
Exception in thread "main" java.lang.RuntimeException: CANNOT EVEN CREATE ARRAYS OF ORIGINAL SIZE!!at edu.stanford.nlp.parser.lexparser.ExhaustivePCFGParser.considerCreatingArrays(ExhaustivePCFGParser.java:2190)at edu.stanford.nlp.parser.lexparser.ExhaustivePCFGParser.parse(ExhaustivePCFGParser.java:347)at edu.stanford.nlp.parser.lexparser.LexicalizedParserQuery.parseInternal(LexicalizedParserQuery.java:258)at edu.stanford.nlp.parser.lexparser.LexicalizedParserQuery.parse(LexicalizedParserQuery.java:536)at edu.stanford.nlp.parser.lexparser.LexicalizedParserQuery.parseAndReport(LexicalizedParserQuery.java:585)at edu.stanford.nlp.parser.lexparser.ParseFiles.parseFiles(ParseFiles.java:213)at edu.stanford.nlp.parser.lexparser.ParseFiles.parseFiles(ParseFiles.java:73)at edu.stanford.nlp.parser.lexparser.LexicalizedParser.main(LexicalizedParser.java:1535)
回答:
这个错误基本上是内存不足错误。它很可能是因为文本中有很长的段落没有句子终止标点符号(句号,问号),所以它一直在尝试解析一个它认为是单个句子的巨大词列表。
解析器通常会在解析失败后继续尝试,但在这种情况下无法继续,因为它既无法为解析更长的句子创建数据结构,也无法重新创建之前使用的数据结构。因此,你需要做一些事情。
选择包括:
- 自己标示句子/短文档的边界。这不需要多次加载解析器(你应该避免这样做)。在命令行中,你可以将每个句子放入一个文件中,并给解析器多个文档进行解析,并要求它将它们保存到不同的文件中(参见
-writeOutputFiles
选项)。 - 或者(可能更好),你可以将所有内容保存在一个文件中,通过将每个句子放在一行,或者使用简单的XML/SGML风格的标签包围每个句子,然后使用
-sentences newline
或-parseInside ELEMENT
。 - 或者你可以通过指定最大句子长度来避免这个问题。未分句的长文本将被跳过。(这对运行时间也很好!)你可以使用
-maxLength 80
来实现这一点。 - 如果你在编写自己的程序,你可以捕获这个异常并尝试恢复。但只有在有足够的内存可用时才会成功,除非你采取了前面提到的步骤。