当我解析包含左右方括号的句子时,解析比句子包含左右括号并且保留默认的normalizeOtherBrackets值为真的更慢,更慢并且不同(我会说20秒vs ParserAnnotator运行3秒钟)。如果将此属性设置为false,则括号与括号的解析时间相当,但解析树仍然非常不同。对于带括号的文本的真值,POS是-LRB-而POS是假的CD,但在每种情况下树的一般子结构都是相同的。
就我的语料库而言,括号绝大多数是为了“澄清先行词”,如this site所述。但是,PRN短语级标签存在于括号中而不是方括号中,因此树的形成本质上是不同的,即使它们在句子中具有接近相同的功能。
那么,请解释解析时间如此不同以及如何才能获得正确的解析?显然,一种简单的方法是用parens替换括号,但这似乎不是一个令人满意的解决方案。有什么设置可以让我有所缓解吗?这是我的代码:
private void execute() {
Properties props = new Properties();
props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner");
props.setProperty("tokenize.options", "normalizeOtherBrackets=false");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
// create an empty Annotation just with the given text
Annotation document = new Annotation(text);
// run all Annotators on this text
pipeline.annotate(document);
// these are all the sentences in this document
// a CoreMap is essentially a Map that uses class objects as keys and has values with custom types
List<CoreMap> sentences = document.get(SentencesAnnotation.class);
long start = System.nanoTime();
ParserAnnotator pa = new ParserAnnotator(DefaultPaths.DEFAULT_PARSER_MODEL, false, 60, new String[0]);
pa.annotate(document);
long end = System.nanoTime();
System.out.println((end - start) / 1000000 + " ms");
for(CoreMap sentence: sentences) {
System.out.println(sentence);
Tree cm = sentence.get(TreeAnnotation.class);
cm.pennPrint();
List<CoreLabel> cm2 = sentence.get(TokensAnnotation.class);
for (CoreLabel c : cm2) {
System.out.println(c);
}
}
}
答案 0 :(得分:1)
是的,这是一个已知(并且非常棘手)的问题,遗憾的是没有完美的解决方案。
这些句子的问题主要是由于这些括号结构不会出现在解析器的训练数据中,也不会出现在词性标注器和解析器交互的情况下。
如果您使用选项normalizeOtherBrackets=true
运行标记生成器,则方括号将替换为-LSB-
和-RSB-
。现在,大多数(或者甚至可能是全部)词性标注器-LSB-
的培训示例都有POS标记-LRB-
,-RSB-
标记为-RRB-
}。因此,尽管考虑了上下文,POS标签器基本上总是将这些标签分配给方括号。
现在如果你在解析器之前运行POS-tagger,那么解析器就会以delexicalized模式运行,这意味着它会尝试根据单个单词的POS标签而不是基于单词本身来解析句子。假设您的句子将具有类似于-LRB- NN -RRB-
的POS序列,则解析器会尝试查找生成规则,以便它可以解析此序列。但是,解析器的训练数据不包含此类序列,因此没有任何此类生成规则,因此解析器无法使用此POS序列解析句子。
当发生这种情况时,解析器进入后退模式,通过为每个单词的所有其他可能的POS标签分配一个非常低的概率来放松对词性标签的约束,以便它最终可以根据句子解析句子。到解析器的生产规则。但是,这一步需要大量计算,因此解析这些句子需要更长的时间。
另一方面,如果您将normalizeOtherBrackets
设置为false
,那么它不会将方括号转换为-LSB-
和-RSB-
,并且POS标记符将会将标签分配给原始[
和]
。但是,我们的训练数据已经过预处理,所有方括号都已被替换,因此[
和]
被视为未知单词,而POS标记器纯粹基于最有可能导致POS序列,它是我们的解析器和标记器的训练数据的一部分。这反过来意味着解析器能够解析句子而无需进入恢复模式,这种速度要快得多。
如果您的数据包含大量具有此类结构的句子,我建议您不要在解析器之前运行POS标记器(通过从注释器列表中删除pos
)。这应该仍然可以提供更快但仍然可靠的解析。否则,如果您有权访问树库,您还可以手动添加一些具有这些构造的树并训练新的解析模型。我不会将normalizeOtherBrackets
设置为false
,因为您的标记化输入将与解析器和标记器的训练数据不同,这可能会给您带来更糟糕的结果。