2016-08-31 3 views
2

Die Eingabe von Text ist immer Liste der Gerichtnamen zu erzeugen, wo es 1 ~ 3 Adjektive und ein SubstantivWie bi/tri-Gramm mit spacigen/nltk

Eingänge

thai iced tea 
spicy fried chicken 
sweet chili pork 
thai chicken curry 

Ausgänge:

Grundsätzlich versuche ich, den Satzbaum zu analysieren und versuche, durch Paarung eines Adjektivs mit dem Substantiv Bigramme zu erzeugen.

Und ich möchte dies mit spacigen erreichen oder NLTK

+0

Siehe http://stackoverflow.com/a/ 34742540/610569 und http: // stackoverflow.com/questions/17531684/n-Gramm-in-Python-vier-fünf-sechs-Gramm – alvas

Antwort

3

Sie diese in wenigen Schritten mit NLTK erreichen können:

  1. PoS markieren, die Sequenzen

  2. die gewünschte n erzeugen -Gramme (in Ihren Beispielen gibt es keine Trigramme, aber Sprung-Gramm, die durch Trigramme erzeugt werden können und dann das mittlere Token ausstanzen)

  3. Alle N-Gramme verwerfen, die nicht mit dem Muster übereinstimmen JJ NN.

Beispiel:

def jjnn_pairs(phrase): 
    ''' 
    Iterate over pairs of JJ-NN. 
    ''' 
    tagged = nltk.pos_tag(nltk.word_tokenize(phrase)) 
    for ngram in ngramise(tagged): 
     tokens, tags = zip(*ngram) 
     if tags == ('JJ', 'NN'): 
      yield tokens 

def ngramise(sequence): 
    ''' 
    Iterate over bigrams and 1,2-skip-grams. 
    ''' 
    for bigram in nltk.ngrams(sequence, 2): 
     yield bigram 
    for trigram in nltk.ngrams(sequence, 3): 
     yield trigram[0], trigram[2] 

Erweitere Muster ('JJ', 'NN') und die gewünschten n-Gramm auf Ihre Bedürfnisse.

Ich denke, es gibt keine Notwendigkeit für das Parsing. Das Hauptproblem dieses Ansatzes ist jedoch, dass die meisten PoS-Tagger nicht alles genau so markieren, wie Sie es möchten. Zum Beispiel markiert die Standard-PoS-Tagger meiner NLTK Installation "Chili" als NN, nicht JJ und "gebraten" bekam VBD. Parsing wird dir dabei allerdings nicht helfen!

0

Etwas wie folgt aus:

>>> from nltk import bigrams 
>>> text = """thai iced tea 
... spicy fried chicken 
... sweet chili pork 
... thai chicken curry""" 
>>> lines = map(str.split, text.split('\n')) 
>>> for line in lines: 
...  ", ".join([" ".join(bi) for bi in bigrams(line)]) 
... 
'thai iced, iced tea' 
'spicy fried, fried chicken' 
'sweet chili, chili pork' 
'thai chicken, chicken curry' 

Alternativ mit colibricorehttps://proycon.github.io/colibri-core/doc/#installation; P

+1

Hey Alvas, ich bin speziell versucht, Adjektiv Adjektiv zu vermeiden. z.B. speziell versuchen zu vermeiden "scharf gebraten" – samol

0

I verwendet spacigen 2.0 mit Englisch-Modell. Ihre Eingabe:

s = ["thai iced tea", 
"spicy fried chicken", 
"sweet chili pork", 
"thai chicken curry",] 

Spacy Lösung:

import spacy 
nlp = spacy.load('en') # import spacy, load model 

def noun_notnoun(phrase): 
    doc = nlp(phrase) # create spacy object 
    token_not_noun = [] 
    notnoun_noun_list = [] 

    for item in doc: 
     if item.pos_ != "NOUN": # separate nouns and not nouns 
      token_not_noun.append(item.text) 
     if item.pos_ == "NOUN": 
      noun = item.text 

    for notnoun in token_not_noun: 
     notnoun_noun_list.append(notnoun + " " + noun) 

    return notnoun_noun_list 

Anruffunktion:

for phrase in s: 
    print(noun_notnoun(phrase)) 

Ergebnisse:

['thai tea', 'iced tea'] 
['spicy chicken', 'fried chicken'] 
['sweet pork', 'chili pork'] 
['thai chicken', 'curry chicken']