2015-12-04 23 views
5

Ich habe die folgende Regex geschriebenWie nltk regex pattern verwenden, um einen bestimmten Phrasenbrocken zu extrahieren?

pattern = """ 
     P2: {<JJ>+ <RB>? <JJ>* <NN>+ <VB>* <JJ>*} 
     P1: {<JJ>? <NN>+ <CC>? <NN>* <VB>? <RB>* <JJ>+} 
     P3: {<NP1><IN><NP2>} 
     P4: {<NP2><IN><NP1>} 

    """ 

Dieses Muster bestimmte Sätze Muster zu markieren, würde einen Satz richtig markieren wie:

a = 'The pizza was good but pasta was bad' 

und gibt den gewünschten Ausgang mit 2 Sätzen:

  1. Pizza war gut
  2. Pasta war schlecht

Wenn aber mein Satz etwas wie:

a = 'The pizza was awesome and brilliant' 

Matches nur der Satz:

'pizza was awesome' 

anstelle des gewünschten:

'pizza was awesome and brilliant' 

Wie kann ich integrieren das Regex-Muster auch für mein zweites Beispiel?

+0

Sprachlich mit POS-Muster, übergeben Ich glaube nicht, dass Sie alle "Pizza war gut" eine Nominalphrase, noch ist es eine Verbalphrase seit Sie den Bestimmer fallen gelassen haben. Es ist mehr wie eine Phrasenstruktur, die Sie extrahieren möchten. – alvas

+0

Grundsätzlich wollte ich Sätze haben, die Gerichte in Bewertungen beschreiben. Keine Nominalphrase. Bearbeitete meine Frage! – pd176

+0

Keine Sorge, ich verstehe, was Sie tun. Es ist für die Stimmungsanalyse richtig? Ich schreibe eine Antwort =) Wollen Sie den Determinator wirklich behalten? – alvas

Antwort

9

Zunächst schauen wir uns die POS-Tags einen Blick darauf werfen, die NLTK gibt:

>>> from nltk import pos_tag 
>>> sent = 'The pizza was awesome and brilliant'.split() 
>>> pos_tag(sent) 
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')] 
>>> sent = 'The pizza was good but pasta was bad'.split() 
>>> pos_tag(sent) 
[('The', 'DT'), ('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ'), ('but', 'CC'), ('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')] 

(Hinweis: Die oben genannten sind die Ausgaben von NLTK v3.1 pos_tag, könnten ältere Version abweichen)

Was Sie aufnehmen möchten, ist im wesentlichen:

  • NN VBD JJ CC JJ
  • NN VBD JJ

lasst sie uns So fangen mit diesen Mustern:

>>> from nltk import RegexpParser 
>>> sent1 = ['The', 'pizza', 'was', 'awesome', 'and', 'brilliant'] 
>>> sent2 = ['The', 'pizza', 'was', 'good', 'but', 'pasta', 'was', 'bad'] 
>>> patterns = """ 
... P: {<NN><VBD><JJ><CC><JJ>} 
... {<NN><VBD><JJ>} 
... """ 
>>> PChunker = RegexpParser(patterns) 
>>> PChunker.parse(pos_tag(sent1)) 
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])]) 
>>> PChunker.parse(pos_tag(sent2)) 
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])]) 

Also das ist "Betrug" von hartzucodieren !!!

Lasst uns an die POS-Muster zurück:

  • NN VBD JJ:

    • NN VBD JJ CC JJ
    • NN VBD JJ

    kann vereinfacht werden (CC JJ)

So können Sie die optionalen Operatoren in der Regex, z.:

>>> patterns = """ 
... P: {<NN><VBD><JJ>(<CC><JJ>)?} 
... """ 
>>> PChunker = RegexpParser(patterns) 
>>> PChunker.parse(pos_tag(sent1)) 
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('awesome', 'JJ'), ('and', 'CC'), ('brilliant', 'JJ')])]) 
>>> PChunker.parse(pos_tag(sent2)) 
Tree('S', [('The', 'DT'), Tree('P', [('pizza', 'NN'), ('was', 'VBD'), ('good', 'JJ')]), ('but', 'CC'), Tree('P', [('pasta', 'NN'), ('was', 'VBD'), ('bad', 'JJ')])]) 

Wahrscheinlich sind Sie die alten Tagger verwenden, das ist, warum Ihre Muster unterschiedlich sind, aber ich denke, Sie sehen, wie Sie die Phrasen, die Sie das obige Beispiel verwenden, müssen erfassen könnten.

Die Schritte sind:

  • Überprüfen Sie zuerst, was die die pos_tag
  • Dann Muster verallgemeinern und vereinfachen, um sie in ihnen
  • Dann die RegexpParser
+0

vielen Dank. Genau was ich brauchte :) – pd176