NLTK Regex Chunker не обрабатывает несколько правил грамматики в одной команде

Я пытаюсь извлечь фразы из моего корпуса, для этого я определил два правила: одно существительное, за которым следуют несколько существительных, а другое прилагательное, за которым следует существительное, здесь я хочу, чтобы, если одна и та же фраза была извлечена из обоих правил, программа должна игнорировать второе, проблема, с которой я сталкиваюсь, заключается в том, что фразы извлекаются только из первого правила, а второе правило не применяется. ниже код:

PATTERN = r"""
      NP: {<NN><NN>+}
      {<ADJ><NN>*}

       """
    MIN_FREQ = 1
    MIN_CVAL = -13 # lowest cval -13
    def __init__(self):
        corpus_root = os.path.abspath('../multiwords/test')
        self.corpus = nltk.corpus.reader.TaggedCorpusReader(corpus_root,'.*')
        self.word_count_by_document = None
        self.phrase_frequencies = None

def calculate_phrase_frequencies(self):
        """
       extract the sentence chunks according to PATTERN and calculate
       the frequency of chunks with pos tags
       """

        # pdb.set_trace()
        chunk_freq_dict = defaultdict(int)
        chunker = nltk.RegexpParser(self.PATTERN)

        for sent in self.corpus.tagged_sents():

            sent = [s for s in sent if s[1] is not None]

            for chk in chunker.parse(sent).subtrees():

                if str(chk).startswith('(NP'):                  

                    phrase = chk.__unicode__()[4:-1]

                    if '\n' in phrase:
                        phrase = ' '.join(phrase.split())

                    just_phrase = ' '.join([w.rsplit('/', 1)[0] for w in phrase.split(' ')])
                   # print(just_phrase)
                    chunk_freq_dict[just_phrase] += 1
        self.phrase_frequencies = chunk_freq_dict
        #print(self.phrase_frequencies)

1 ответ

Решение

Прежде всего, Python и особенно многострочные строки зависят от отступа. Убедитесь, что в строке нет предшествующих пробелов (так как они будут рассматриваться как символы), и убедитесь, что шаблоны (скобки) выровнены визуально.

Кроме того, я думаю, что вы можете иметь <ADJ><NN>+ как ваш второй образец. + означает 1 или более, тогда как * означает 0 или больше.

Я надеюсь, что это решает проблему.

#!/usr/bin/env python
import nltk

PATTERN = r"""
NP: {<NN><NN>+}
    {<ADJ><NN>+}
"""

sentence = [('the', 'DT'), ('little', 'ADJ'), ('yellow', 'ADJ'),
            ('shepherd', 'NN'), ('dog', 'NN'), ('barked', 'VBD'), ('at', 'IN'),
            ('the', 'DT'), ('silly', 'ADJ'), ('cat', 'NN')]

cp = nltk.RegexpParser(PATTERN)
print(cp.parse(sentence))

Результат:

(S
  the/DT
  little/ADJ
  yellow/ADJ
  (NP shepherd/NN dog/NN)
  barked/VBD
  at/IN
  the/DT
  (NP silly/ADJ cat/NN))

Ссылка: http://www.nltk.org/book/ch07.html

Другие вопросы по тегам