2017-03-11 8 views
0

NLTKの正規表現パーサーで文法の一部としてnot条件を作成する必要があります。私は構造'Coffee & Tea'である単語をチャンクしたいですが、シーケンスの前にタイプ<IN>の単語があれば、それはチャンクしてはいけません。たとえば、'in London and Paris'はパーサによってチャンクされるべきではありません。次のようにNLTKの正規表現パーサーでない条件

私のコードは次のとおりです。

grammar = r'''NP: {(^<IN>)<NNP>+<CC><NN.*>+}''' 

私は問題を解決するために上記の文法を試みたが、誰かが私が間違っているのを教えてください可能性があり、それが機能していません。

例:

def parse_sentence(sentence): 
    pos_sentence = nltk.pos_tag(nltk.word_tokenize(sentence)) 
    grammar = r'''NP: {<NNP>+<CC><NN.*>+}''' 
    parser = nltk.RegexpParser(grammar) 
    result = parser.parse(pos_sentence) 
    print result 

sentence1 = 'Who is the front man of the band that wrote Coffee & TV?' 
parse_sentence(sentence1) 

sentence2 = 'Who of those resting in Westminster Abbey wrote a book set in London and Paris?' 
parse_sentence(sentence2) 

Result for sentence 1 is: 
(S 
    Who/WP 
    is/VBZ 
    the/DT 
    front/JJ 
    man/NN 
    of/IN 
    the/DT 
    band/NN 
    that/WDT 
    wrote/VBD 
    (NP Coffee/NNP &/CC TV/NN) 
    ?/.) 

Result for sentence2 is: 
(S 
    Who/WP 
    of/IN 
    those/DT 
    resting/VBG 
    in/IN 
    Westminster/NNP 
    Abbey/NNP 
    wrote/VBD 
    a/DT 
    book/NN 
    set/VBN 
    in/IN 
    (NP London/NNP and/CC Paris/NNP) 
    ?/.) 

sentence1とsentence2フレーズCoffee & Teaの両方で見ることができると私はチャンクLondon and Parisを望むものではないがLondon and Parisは、グループとしてのチャンクを取得したよう。これを行う1つの方法は、先行する<IN> POSタグのパターンを無視することです。

一言で言えば、POSタグのNOT(否定)条件を正規表現パーサーの文法に追加する方法を知る必要があります。 '^'の後にタグ定義を使用する標準的な構文は機能していないようです。

+0

あなたはこれをどのように使用しているか、より多くの文脈を与えることができますか?あなたが[MCVE]を提供した方が簡単でしょう。 –

+0

私は質問に例を追加しています。私はちょうど正規表現パーサーでPOSタグのNOT(否定)条件を追加する方法を知る必要があります。 '^'の後にタグ定義を使用する標準的な構文は機能していないようです。 –

+0

正規表現では、 '^'は通常、行の先頭を意味します。文字クラス(角括弧)の中で "not"を意味するだけです。 – alexis

答えて

2

"負のlookbehind"表現が必要です。残念ながら、それはチャンクパーサーでは機能しませんので、あなたが望むものはチャンク正規表現として指定することはできません。

通常のネガティブヒアビハインドです: "Paris"にマッチしますが、 "and"で始まる場合はマッチしません。

>>> re.findall(r"(?<!and) Paris", "Search in London and Paris etc.") 
[] 

残念ながら、対応するルックバックヒントチャンクルールは機能しません。 nltkの正規表現エンジンは、POSタイプを解釈するためにそれを渡す正規表現を調整し、lookbehindによって混乱します。 (私は後読み構文で<文字がタグの区切り文字として誤解されて推測している。)

>>> parser = nltk.RegexpParser(r"NP: {(?<!<IN>)<NNP>+<CC><NN.*>+}") 
... 
ValueError: Illegal chunk pattern: {(?<!<IN>)<NNP>+<CC><NN.*>+} 
0

cp.2.5「Chinking」

を「私たちは、その一連のトークンであることを割れ目を定義することができますチャンク」に含まれていないこと

http://www.nltk.org/book/ch07.html

除外の逆中括弧を参照してください

grammar = 
     r""" 
      NP: 
      {<.*>+}   # Chunk everything 
      }<VBD|IN>+{  # Chink sequences of VBD and IN 

     """ 
+0

NLTKについてはわかりませんが、「ロンドンとパリ」という質問の例では、「in」だけをchunkingから除外する必要があるだけでなく、それ以外の場合は「London and Paris」 。しかし、この答えを説明するために展開することができれば、私は気にしません。 –