Natural Language Toolkit - Transforming Chunks

Por que transformar Chunks?

Até agora, temos pedaços ou frases de sentenças, mas o que devemos fazer com eles. Uma das tarefas importantes é transformá-los. Mas por que? É fazer o seguinte -

  • correção gramatical e
  • reorganizando frases

Filtrando palavras insignificantes / inúteis

Suponha que se você deseja julgar o significado de uma frase, então existem muitas palavras comumente usadas, como 'o', 'a', são insignificantes ou inúteis. Por exemplo, veja a seguinte frase -

'O filme foi bom'.

Aqui, as palavras mais significativas são 'filme' e 'bom'. Outras palavras, 'o' e 'era' são ambos inúteis ou insignificantes. É porque sem eles também podemos obter o mesmo significado da frase. 'Bom filme'.

Na seguinte receita do Python, aprenderemos como remover palavras inúteis / insignificantes e manter as palavras significativas com a ajuda de tags POS.

Exemplo

Primeiro, olhando através treebankcorpus para palavras irrelevantes, precisamos decidir quais tags de classes gramaticais são significativas e quais não são. Vejamos a seguinte tabela de palavras e tags insignificantes -

Palavra Tag
uma DT
Todos PDT
A DT
E CC
Ou CC
que WDT
o DT

Na tabela acima, podemos ver, além de CC, todas as outras tags terminam com DT, o que significa que podemos filtrar palavras insignificantes observando o sufixo da tag.

Para este exemplo, vamos usar uma função chamada filter()que pega um único pedaço e retorna um novo pedaço sem nenhuma palavra com tag insignificante. Esta função filtra quaisquer tags que terminam com DT ou CC.

Exemplo

import nltk
def filter(chunk, tag_suffixes=['DT', 'CC']):
   significant = []
   for word, tag in chunk:
      ok = True
      for suffix in tag_suffixes:
         if tag.endswith(suffix):
            ok = False
            break
      if ok:
         significant.append((word, tag))
   return (significant)

Agora, vamos usar esta função filter () em nossa receita Python para excluir palavras insignificantes -

from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])

Resultado

[('good', 'JJ'), ('movie', 'NN')]

Correção de Verbo

Muitas vezes, na linguagem do mundo real, vemos formas verbais incorretas. Por exemplo, 'você está bem?' não está correto. A forma do verbo não está correta nesta frase. A frase deve ser 'você está bem?' O NLTK nos fornece a maneira de corrigir esses erros criando mapeamentos de correção de verbos. Esses mapeamentos de correção são usados ​​dependendo se há um substantivo plural ou singular no bloco.

Exemplo

Para implementar a receita Python, primeiro precisamos definir os mapeamentos de correção de verbo. Vamos criar dois mapeamentos da seguinte maneira -

Plural to Singular mappings

plural= {
   ('is', 'VBZ'): ('are', 'VBP'),
   ('was', 'VBD'): ('were', 'VBD')
}

Singular to Plural mappings

singular = {
   ('are', 'VBP'): ('is', 'VBZ'),
   ('were', 'VBD'): ('was', 'VBD')
}

Como visto acima, cada mapeamento possui um verbo marcado que mapeia para outro verbo marcado. Os mapeamentos iniciais em nosso exemplo cobrem o básico dos mapeamentosis to are, was to were, e vice versa.

A seguir, definiremos uma função chamada verbs(), no qual você pode passar um trecho com a forma verbal incorreta e obter um trecho corrigido de volta. Para fazer isso,verb() função usa uma função auxiliar chamada index_chunk() que irá pesquisar o pedaço para a posição da primeira palavra marcada.

Vamos ver essas funções -

def index_chunk(chunk, pred, start = 0, step = 1):
   l = len(chunk)
   end = l if step > 0 else -1
   for i in range(start, end, step):
      if pred(chunk[i]):
         return i
      return None
def tag_startswith(prefix):
   def f(wt):
      return wt[1].startswith(prefix)
   return f

def verbs(chunk):
   vbidx = index_chunk(chunk, tag_startswith('VB'))
   if vbidx is None:
      return chunk
   verb, vbtag = chunk[vbidx]
   nnpred = tag_startswith('NN')
   nnidx = index_chunk(chunk, nnpred, start = vbidx+1)
   if nnidx is None:
      nnidx = index_chunk(chunk, nnpred, start = vbidx-1, step = -1)
   if nnidx is None:
      return chunk
   noun, nntag = chunk[nnidx]
   if nntag.endswith('S'):
      chunk[vbidx] = plural.get((verb, vbtag), (verb, vbtag))
   else:
      chunk[vbidx] = singular.get((verb, vbtag), (verb, vbtag))
   return chunk

Salve essas funções em um arquivo Python em seu diretório local onde Python ou Anaconda está instalado e execute-o. Eu salvei comoverbcorrect.py.

Agora vamos ligar verbs() função em um POS marcado is you fine pedaço -

from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])

Resultado

[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]

Eliminando voz passiva de frases

Outra tarefa útil é eliminar a voz passiva das frases. Isso pode ser feito com a ajuda de trocar as palavras em torno de um verbo. Por exemplo,‘the tutorial was great’ pode ser transformado em ‘the great tutorial’.

Exemplo

Para conseguir isso, estamos definindo uma função chamada eliminate_passive()que irá trocar o lado direito do pedaço com o lado esquerdo usando o verbo como ponto de pivô. A fim de encontrar o verbo para girar, ele também usará oindex_chunk() função definida acima.

def eliminate_passive(chunk):
   def vbpred(wt):
      word, tag = wt
      return tag != 'VBG' and tag.startswith('VB') and len(tag) > 2
   vbidx = index_chunk(chunk, vbpred)
   if vbidx is None:
      return chunk
   return chunk[vbidx+1:] + chunk[:vbidx]

Agora vamos ligar eliminate_passive() função em um POS marcado the tutorial was great pedaço -

from passiveverb import eliminate_passive
eliminate_passive(
   [
      ('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
   ]
)

Resultado

[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]

Troca de cardinais substantivos

Como sabemos, uma palavra cardinal como 5 é marcada como CD em um bloco. Essas palavras cardinais geralmente ocorrem antes ou depois de um substantivo, mas para fins de normalização, é útil colocá-las sempre antes do substantivo. Por exemplo, a dataJanuary 5 pode ser escrito como 5 January. Vamos entender isso com o seguinte exemplo.

Exemplo

Para conseguir isso, estamos definindo uma função chamada swapping_cardinals()que irá trocar qualquer cardinal que ocorra imediatamente após um substantivo pelo substantivo. Com isso, o cardeal ocorrerá imediatamente antes do substantivo. Para fazer comparação de igualdade com a tag fornecida, ele usa uma função auxiliar que chamamos detag_eql().

def tag_eql(tag):
   def f(wt):
      return wt[1] == tag
   return f

Agora podemos definir swapping_cardinals () -

def swapping_cardinals (chunk):
   cdidx = index_chunk(chunk, tag_eql('CD'))
   if not cdidx or not chunk[cdidx-1][1].startswith('NN'):
      return chunk
   noun, nntag = chunk[cdidx-1]
   chunk[cdidx-1] = chunk[cdidx]
   chunk[cdidx] = noun, nntag
   return chunk

Agora, vamos ligar swapping_cardinals() função em um encontro “January 5” -

from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])

Resultado

[('10', 'CD'), ('January', 'NNP')]
10 January