Python 如何使用spacy/nltk生成bi/TRIG

Python 如何使用spacy/nltk生成bi/TRIG,python,nlp,nltk,n-gram,spacy,Python,Nlp,Nltk,N Gram,Spacy,输入文本总是菜名列表,其中有1~3个形容词和一个名词 投入 thai iced tea spicy fried chicken sweet chili pork thai chicken curry 产出: thai tea, iced tea spicy chicken, fried chicken sweet pork, chili pork thai chicken, chicken curry, thai curry 基本上,我希望解析句子树,并尝试通过将形容词与名词配对来生成双格

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

投入

thai iced tea
spicy fried chicken
sweet chili pork
thai chicken curry
产出:

thai tea, iced tea
spicy chicken, fried chicken
sweet pork, chili pork
thai chicken, chicken curry, thai curry
基本上,我希望解析句子树,并尝试通过将形容词与名词配对来生成双格


我想通过spacy或nltk实现这一点,您可以通过nltk通过几个步骤实现:

  • PoS标记序列

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

  • 丢弃所有与模式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]
    
    扩展模式
    ('JJ','NN')
    和所需的n-gram以满足您的需要

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

    类似这样:

    >>> 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'
    


    或者使用
    colibricore
    ;P

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

    你的意见:

    s = ["thai iced tea",
    "spicy fried chicken",
    "sweet chili pork",
    "thai chicken curry",]
    
    空间解决方案:

    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
    
    调用函数:

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

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

    嘿,阿尔瓦斯,我特别想避免使用形容词。e、 特别是要避免“辛辣油炸”,如果你能用文字(而不仅仅是代码)描述你的算法,那就好了。它应该做什么?它对更长的序列有效吗?我注意到你的方法没有保持词序;例如,输出包含“咖喱鸡”,尽管“咖喱”在输入中从未出现在“鸡”之前。添加了一些注释。是的,它没有-我没有认为这是一个要求。