2017-06-06 6 views
1

Gibt es eine Möglichkeit, NLTK zu verwenden, um eine Reihe von möglichen Wortarten einer einzelnen Zeichenfolge zu erhalten, unter Berücksichtigung, dass verschiedene Wörter Homonyme haben können?NLTK Wort-Wort-Tagging

Zum Beispiel: Bericht -> {Substantiv, Verb}, Art -> {Adjektiv, Substantiv}

Ich habe nicht in der Lage gewesen, um einen POS-tokenizer zu finden, die außerhalb der für Worte part-of-speech-Tags der Kontext eines ganzen Satzes. Dies scheint eine sehr grundlegende Anforderung von NLTK zu sein, so dass ich verwirrt bin, warum ich so viel Mühe hatte, es zu finden.

Antwort

1

Ja. Der einfachste Weg besteht darin, keinen Tagger zu verwenden, sondern einfach einen oder mehrere Korpora zu laden und die Menge aller Tags für das Wort zu sammeln, an dem Sie interessiert sind. Wenn Sie an mehr als einem Wort interessiert sind, ist es am einfachsten, die Tags zu sammeln für alle Wörter im Korpus, dann schau nach oben, was du willst. Ich füge Frequenzzählungen hinzu, nur weil ich es kann. Zum Beispiel unter Verwendung des braunen Korpus und des einfachen "universellen" Tagsets:

>>> wordtags = nltk.ConditionalFreqDist((w.lower(), t) 
     for w, t in nltk.corpus.brown.tagged_words(tagset="universal")) 
>>> wordtags["report"] 
FreqDist({'NOUN': 135, 'VERB': 39}) 
>>> list(wordtags["kind"]) 
['ADJ', 'NOUN'] 
2

Da POS-Modelle auf satz-/dokumentenbasierten Daten trainiert werden, ist die erwartete Eingabe für das vortrainierte Modell ein Satz/Dokument. Wenn es nur ein einzelnes Wort gibt, behandelt es es als einen einzelnen Wortsatz, daher sollte es nur einen Tag in diesem einzelnen Wortsatzkontext geben.

Wenn Sie versuchen, alle möglichen POS-Tags pro englischen Wörtern zu finden, würden Sie einen Korpus von vielen verschiedenen Gebrauch der Wörter benötigen und dann den Korpus markieren und die Zahl zählen/extrahieren. von Tags pro Wort. Z.B.

>>> from nltk import pos_tag 
>>> sent1 = 'The coaches are going from Singapore to Frankfurt' 
>>> sent2 = 'He coaches the football team' 
>>> pos_tag(sent1.split()) 
[('The', 'DT'), ('coaches', 'NNS'), ('are', 'VBP'), ('going', 'VBG'), ('from', 'IN'), ('Singapore', 'NNP'), ('to', 'TO'), ('Frankfurt', 'NNP')] 
>>> pos_tag(sent2.split()) 
[('He', 'PRP'), ('coaches', 'VBZ'), ('the', 'DT'), ('football', 'NN'), ('team', 'NN')] 

>>> from collections import defaultdict, Counter 
>>> counts = defaultdict(Counter) 
>>> tagged_sents = [pos_tag(sent) for sent in [sent1.split(), sent2.split()]] 

>>> for word, pos in chain(*tagged_sents): 
...  counts[word][pos] += 1 
... 

>>> counts 
defaultdict(<class 'collections.Counter'>, {'from': Counter({'IN': 1}), 'to': Counter({'TO': 1}), 'Singapore': Counter({'NNP': 1}), 'football': Counter({'NN': 1}), 'coaches': Counter({'VBZ': 1, 'NNS': 1}), 'going': Counter({'VBG': 1}), 'are': Counter({'VBP': 1}), 'team': Counter({'NN': 1}), 'The': Counter({'DT': 1}), 'Frankfurt': Counter({'NNP': 1}), 'the': Counter({'DT': 1}), 'He': Counter({'PRP': 1})}) 

>>> counts['coaches'] 
Counter({'VBZ': 1, 'NNS': 1}) 

Alternativ gibt es WordNet:

>>> from nltk.corpus import wordnet as wn 
>>> wn.synsets('coaches') 
[Synset('coach.n.01'), Synset('coach.n.02'), Synset('passenger_car.n.01'), Synset('coach.n.04'), Synset('bus.n.01'), Synset('coach.v.01'), Synset('coach.v.02')] 
>>> [ss.pos() for ss in wn.synsets('coaches')] 
[u'n', u'n', u'n', u'n', u'n', u'v', u'v'] 
>>> Counter([ss.pos() for ss in wn.synsets('coaches')]) 
Counter({u'n': 5, u'v': 2}) 

Aber das beachten WordNet eine manuell erstellten Resource ist, so dass Sie nicht jedes englische Wort in es erwarten kann.