2016-02-12 50 views
0

當我解析一個包含左右方括號的句子時,解析速度要比包含左右括號和默認normalizeOtherBrackets值的句子慢很多且不同保持真實(我會說20秒vs ParserAnnotator運行3秒)。如果這是屬性而不是設置爲false,則括號與括號的解析時間相當可比,但解析樹仍然非常不同。對於帶有括號的文本的真實值,POS是-LRB,而POS是CD,但是在每種情況下樹的一般子結構都是相同的。解決流水中概念上處理方括號vs括號的方法

對於我的語料庫,括號絕大部分是爲了「澄清先行詞」,如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); 
     } 
    }  
} 

回答

1

是的,這是一個已知(而且非常棘手)的問題,不幸的是沒有完美的解決方案。

這樣的句子的問題主要是由於這些括號結構沒有出現在解析器的訓練數據中以及詞性標註器和解析器相互作用的方式造成的。

如果使用選項normalizeOtherBrackets=true運行標記器,則方括號將被替換爲-LSB--RSB-。現在,在詞性標註器-LSB-的大多數(或甚至全部)訓練示例中,具有標籤-LRB--RSB-具有標籤-RRB-。因此,儘管考慮了上下文,POS標籤器基本上總是將這些標籤分配到方括號中。

現在,如果您在解析器之前運行POS-tagger,那麼解析器將以delexicalized模式運行,這意味着它會嘗試根據單詞的POS標籤解析句子,而不是基於單詞本身。假設您的句子將具有類似於-LRB- NN -RRB-的POS序列,則解析器會嘗試查找生產規則,以便它可以解析此序列。然而,解析器的訓練數據不包含這樣的序列,因此沒有任何這樣的生產規則,因此解析器不能用這個POS序列解析句子。

當發生這種情況時,解析器進入回退模式,通過爲每個單詞的所有其他可能的POS標籤分配一個非常低的概率來放鬆對詞性標籤的約束,以便它最終可以解析句子根據解析器的生產規則。然而,這一步需要大量的計算,因此解析這些句子需要很長的時間。

在另一方面,如果設置normalizeOtherBracketsfalse,那麼就不會方括號轉化爲-LSB--RSB-和POS惡搞將標記指定給原[]。然而,我們的訓練數據已經過預處理,因此所有方括號已被替換,因此[]被視爲未知單詞,並且POS標記器純粹基於上下文分配標記,這很可能會導致作爲訓練一部分的POS序列我們的解析器和標記器的數據。作爲回報,這意味着解析器能夠解析句子而無需進入更快的恢復模式。

如果您的數據包含很多帶有此類構造的句子,我建議您不要在解析器之前運行POS標記器(通過從註釋器列表中刪除pos)。這應該仍然給你更快但仍然可靠的分析。否則,如果您有權訪問樹形庫,則還可以手動添加具有這些構造的幾棵樹並訓練一個新的解析模型。我不會將normalizeOtherBrackets設置爲false,因爲那樣您的標記化輸入將與解析器和標記器的訓練數據不同,這可能會給您帶來更糟糕的結果。

+0

謝謝,這可以幫助我解決很多問題。現在我將開始工作並嘗試一些關於我的語料庫的建議。 – demongolem