我正在使用命令行中的Stanford CoreNLP管道来依赖解析大型文档,并且非常重要的是文档中的每一行都会收到自己的依赖关系树(否则其他内容将不对齐)。这对线目前让我感到悲伤:
<!-- copy from here --> <a href="http://strategis.gc.ca/epic/internet/inabc-eac.nsf/en/home"><img src="id-images/ad-220x80_01e.jpg" alt="Aboriginal Business Canada:
Opening New Doors for Your Business" width="220" height="80" border="0"></a> <!-- copy to here --> Small ABC Graphic Instructions 1.
这是我正在使用的命令:
java -cp "*" -Xmx1g -Xss515m edu.stanford.nlp.pipeline.StanfordCoreNLP \
-annotators tokenize,ssplit,pos,depparse \
-ssplit.eolonly true \
-ssplit.newlineIsSentenceBreak always \
-outputFormat conllu \
-file "input.txt"
这是结果输出:
1 <!-- copy from here --> _ _ JJ _ 9 amod _ _
2 <a href="http://strategis.gc.ca/epic/internet/inabc-eac.nsf/en/home"> _ _ JJ _ 9 amod _ _
3 <img src="id-images/ad-220x80_01e.jpg" alt="Aboriginal Business Canada:
Opening New Doors for Your Business" width="220" height="80" border="0"> _ _ NN _ 9 compound _ _
4 </a> _ _ NN _ 9 compound _ _
5 <!-- copy to here --> _ _ NN _ 9 compound _ _
6 Small _ _ JJ _ 9 amod _ _
7 ABC _ _ NNP _ 9 compound _ _
8 Graphic _ _ NNP _ 9 compound _ _
9 Instructions _ _ NNS _ 0 root _ _
10 1 _ _ CD _ 9 nummod _ _
11 . _ _ . _ 9 punct _ _
看起来HTML标记中引号内的换行符被解释为令牌的一部分,而不是句子中断。这是特殊的,因为我正在使用-ssplit.newlineIsSentenceBreak always
标志,我希望它会强制解析器拆分HTML代码。但是,即使我不需要每一行来获得自己的解析,这种行为也很麻烦,因为生成的文件不再是有效的conllu格式,因为第3行只有两个以制表符分隔的列(而不是所需的10)而第4行只有9个。
我使用过的一个解决方法是将原始文件中的每一行转换为自己的文件,然后使用-filelist
参数将其输入,但这会产生过多的stdout
输出,从而减慢了速度堵塞了终端。我尝试将输出重定向到/dev/null
或打开“安静模式”时遇到了失败,但这可能是另一个帖子的问题。
我尝试了双倍间距文件,但这没有帮助。使用sed 's/"/\\"/g'
预处理文本确实通过破坏管道将其识别为HTML代码的能力来解决此问题,但引入了新的问题,因为解析器可能未在转义的引号上进行过培训。
显然这是一个奇怪的句子,我不希望输出被合理地解析,但我确实需要它被合理地格式化。有什么提示吗?
更新 有人建议我尝试使用cleanxml注释器完全删除HTML标签。这减少了文件中的行数,这可能导致稍后的错位,但由于HTML标签无法合理地解析,因此摆脱它们似乎独立有利。我稍后会再次更新,但这是否适用于我的目的,但我同时也接受其他建议。
答案 0 :(得分:1)
这里有两个问题:
标记生成器将解析为单个标记HTML / XML / SGML标记,其中属性的引用值按行分割。通常这是一件好事 - 如果这是常规文本,那么它为这个例子做的事情实际上是合理的,将整个img
标记保持在一起 - 但如果你想要严格地处理文本一句话,那将是灾难性的每行,与大多数机器翻译语料库一样。在这种情况下,您希望将每一行视为一个句子,即使原始句子错误地完成,也就是在这里。
如果在属性值中捕获换行符,则将其保留为原样,然后在输出时,这会破坏至少面向行的CoNLL和CoNLL-U输出格式的完整性。
我添加/更改了代码以解决这些问题:
有一个新的标记生成器选项:-tokenize.options tokenizePerLine
,它将禁止标记生成器在形成标记或做出标记化决策时查看线条边界。 (此选项可以在逗号分隔列表中与所有其他tokenize.options
选项组合使用。)
如果在属性值中捕获换行符,则会将其映射到U+00A0
(非中断空格)。这已经是U+0020
(空间)发生的事情,现在也是为新行完成的。这修复了CoNLL / CoNLL-U输出并为Stanford CoreNLP维护了正确的不变量:令牌可能偶尔包含不间断空格,但从不包含空格或换行符。
此问题已在the CoreNLP github上的提交0a17fe4c0fc4ccfb095f474bf113d1df0c6d17cb中修复。如果你抓住那个版本 - 或者最低限度地更新PTBLexer.class
和PTBTokenizer.class
,那么你将拥有这个新选项并且应该是好的。以下命令可以为您提供所需内容:
java -cp "*" -Xmx1g edu.stanford.nlp.pipeline.StanfordCoreNLP \
-annotators tokenize,ssplit,pos,depparse -ssplit.eolonly true \
-tokenize.options tokenizePerLine -outputFormat conllu -file "input.txt"
P.S。我猜你试图解决问题,但如果你正在使用-ssplit.eolonly true
,那么你不应该需要或看到与-ssplit.newlineIsSentenceBreak always
的区别。此外,我们也许应该这样做,以便启用-ssplit.eolonly true
自动打开-tokenize.options tokenizePerLine
,但目前情况并非如此......