如何使用spacy/nltk生成bi/tri-gram

sam*_*mol 8 python nlp nltk n-gram spacy

输入文本总是菜名列表,其中有1~3个形容词和一个名词

输入

thai iced tea
spicy fried chicken
sweet chili pork
thai chicken curry
Run Code Online (Sandbox Code Playgroud)

输出:

thai tea, iced tea
spicy chicken, fried chicken
sweet pork, chili pork
thai chicken, chicken curry, thai curry
Run Code Online (Sandbox Code Playgroud)

基本上,我希望解析句子树并尝试通过将形容词与名词配对来生成二元词.

我想用spacy或nltk实现这一目标

len*_*enz 5

您可以使用 NLTK 通过几个步骤来实现这一点:

  1. PoS 标记序列

  2. 生成所需的 n-gram(在您的示例中没有三元组,但是可以通过三元组生成然后冲出中间标记的跳过元组)

  3. 丢弃所有与模式JJ NN不匹配的 n-gram 。

例子:

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]
Run Code Online (Sandbox Code Playgroud)

('JJ', 'NN')根据您的需要扩展模式和所需的 n-gram。

我认为没有必要解析。然而,这种方法的主要问题是大多数 PoS 标记器可能不会完全按照您想要的方式标记所有内容。例如,我的 NLTK 安装的默认 PoS 标记器将“chili”标记为NN,而不是JJ,而“fried”标记为VBD。但是,解析不会帮助您解决这个问题!


Pet*_*ska 5

我将spacy 2.0与英语模型一起使用。要找到名词和“非名词”来解析输入,然后将非名词和名词放在一起以创建所需的输出。

您的输入:

s = ["thai iced tea",
"spicy fried chicken",
"sweet chili pork",
"thai chicken curry",]
Run Code Online (Sandbox Code Playgroud)

空间解决方案:

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
Run Code Online (Sandbox Code Playgroud)

通话功能:

for phrase in s:
    print(noun_notnoun(phrase))
Run Code Online (Sandbox Code Playgroud)

结果:

['thai tea', 'iced tea']
['spicy chicken', 'fried chicken']
['sweet pork', 'chili pork']
['thai chicken', 'curry chicken']
Run Code Online (Sandbox Code Playgroud)