2016-08-24 4 views
0

I NLTK des RegexpParser zu Chunk eine Nominalphrase bin mit, die ich mit einer Grammatik alsNLTK RegexpParser, Satz Brocken mit genau einem Element passend

definieren
grammar = "NP: {<DT>?<JJ>*<NN|NNS>+}" 
cp = RegexpParser(grammar) 

Das ist großartig, es ist passend zu einer Nominalphrase als :

  • DT wenn es vorhanden ist
  • JJ in jeglicher Anzahl
  • NN oder NNS mindestens ein

Nun, was ist, wenn ich will, das Gleiche passen, aber die was Zahl für JJ in man nur verwandelt zu haben? Also ich möchte DT, wenn es existiert, eins JJ und 1+ NN/NNS. Wenn es mehr als einen JJ gibt, möchte ich nur einen von ihnen, den am nächsten zum Nomen (und DT, wenn es gibt, und NN/NNS).

Die Grammatik

grammar = "NP: {<DT>?<JJ><NN|NNS>+}" 

nur passen würde, wenn es nur eine JJ ist, die Grammatik

grammar = "NP: {<DT>?<JJ>{1}<NN|NNS>+}" 

die ich dachte, würde die typical Regexp patterns gegeben arbeiten, wirft ein Valueerror.

Zum Beispiel, in "Dieser schöne grüne Rock" möchte ich "Dieser grüne Rock" klumpen.

Also, wie würde ich fortfahren?

+0

Grammatik = "NP: {?

+}" ist richtig. Kannst du ein Beispiel geben, wo es keinen Determinator gab? – RAVI

+2

Weil es in Ihrem Beispiel 2 JJs gibt. Sie sagten - "Ich möchte DT, wenn es existiert, ein JJ und 1 + NN/NNS." – RAVI

+0

@RAVI, sieht aus, als ob du genau richtig liegst, das erklärt das Problem. Sie sollten es in eine Antwort erweitern, die das OP akzeptieren kann. – alexis

Antwort

1

Grammer grammar = "NP: {<DT>?<JJ><NN|NNS>+}" ist korrekt für Ihre erwähnte Anforderung.

Das Beispiel, das Sie in Kommentarbereich gab, wo Sie sind nicht in der Ausgabe bekommen DT -

"This beautiful green skirt is for you." 

Tree('S', [('This', 'DT'), ('beautiful', 'JJ'), Tree('NP', [('green','JJ'), 
('skirt', 'NN')]), ('is', 'VBZ'), ('for', 'IN'), ('you', 'PRP'), ('.', '.')]) 

Hier in Ihrem Beispiel gibt es 2 consecutive JJs, die Ihre Anforderungen nicht erfüllen, wie Sie gesagt hat - "I want to match DT if it exists, one JJ and 1+ NN/NNS."


Für aktuelle Anforderung - I want to match DT if it exists, one JJ and 1+ NN/NNS. If there are more than one JJ, I want to match only one of them, the one nearest to the noun (and DT if there is, and NN/NNS).

Hier Sie müssen

grammar = "NP: {<DT>?<JJ>*<NN|NNS>+}" 

verwenden und Nachbearbeitung der NP-Chunks, um zusätzliche JJ zu entfernen.

Code:

from nltk import Tree 

chunk_output = Tree('S', [Tree('NP', [('This', 'DT'), ('beautiful', 'JJ'), ('green','JJ'), ('skirt', 'NN')]), ('is', 'VBZ'), ('for', 'IN'), ('you', 'PRP'), ('.', '.')]) 

for child in chunk_output: 
    if isinstance(child, Tree):    
     if child.label() == 'NP': 
      for num in range(len(child)): 
       if not (child[num][1]=='JJ' and child[num+1][1]=='JJ'): 
        print child[num][0] 

Ausgang:

This 
green 
skirt 
+0

Richtig, also gibt es keine Möglichkeit dem Parser zu sagen, dass ich nur einen direkt haben möchte. –

+0

Ja, das ist nicht möglich, da Sie dazwischen etwas überspringen möchten. Wenn Sie wissen, wie das Regex-Matching funktioniert, werden Sie es verstehen. – RAVI

Verwandte Themen