Kit de herramientas de lenguaje natural: transformación de fragmentos

¿Por qué transformar Chunks?

Hasta ahora tenemos fragmentos o frases de oraciones, pero ¿qué se supone que debemos hacer con ellas? Una de las tareas importantes es transformarlos. ¿Pero por qué? Es hacer lo siguiente:

  • corrección gramatical y
  • reordenando frases

Filtrar palabras insignificantes / inútiles

Suponga que si desea juzgar el significado de una frase, hay muchas palabras de uso común, como "la", "a", que son insignificantes o inútiles. Por ejemplo, vea la siguiente frase:

'La película fue buena'.

Aquí las palabras más significativas son "película" y "bueno". Otras palabras, 'el' y 'era' son inútiles o insignificantes. Es porque sin ellos también podemos obtener el mismo significado de la frase. 'Buena película'.

En la siguiente receta de Python, aprenderemos cómo eliminar palabras inútiles / insignificantes y mantener las palabras significativas con la ayuda de etiquetas POS.

Ejemplo

Primero, mirando a través treebankcorpus para palabras vacías, necesitamos decidir qué etiquetas de parte del discurso son significativas y cuáles no. Veamos la siguiente tabla de palabras y etiquetas insignificantes:

Palabra Etiqueta
un DT
Todas PDT
Un DT
Y CC
O CC
Ese WDT
los DT

En la tabla anterior, podemos ver que, además de CC, todas las demás etiquetas terminan con DT, lo que significa que podemos filtrar palabras insignificantes mirando el sufijo de la etiqueta.

Para este ejemplo, usaremos una función llamada filter()que toma un solo fragmento y devuelve un nuevo fragmento sin ninguna palabra etiquetada insignificante. Esta función filtra las etiquetas que terminan en DT o CC.

Ejemplo

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)

Ahora, usemos esta función filter () en nuestra receta de Python para eliminar palabras insignificantes -

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

Salida

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

Corrección de verbos

Muchas veces, en el lenguaje del mundo real vemos formas verbales incorrectas. Por ejemplo, '¿estás bien?' no es correcto. La forma verbal no es correcta en esta oración. La oración debería ser '¿estás bien?' NLTK nos proporciona la forma de corregir tales errores mediante la creación de asignaciones de corrección de verbos. Estos mapeos de corrección se utilizan dependiendo de si hay un sustantivo plural o singular en el fragmento.

Ejemplo

Para implementar la receta de Python, primero necesitamos definir asignaciones de corrección de verbos. Creemos dos mapas de la siguiente manera:

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 se vio anteriormente, cada mapeo tiene un verbo etiquetado que se asigna a otro verbo etiquetado. Las asignaciones iniciales en nuestro ejemplo cubren lo básico de las asignacionesis to are, was to were, y viceversa.

A continuación, definiremos una función llamada verbs(), en el que puedes pasar una grieta con la forma verbal incorrecta y obtendrás una parte corregida. Para hacerloverb() La función usa una función auxiliar llamada index_chunk() que buscará en el fragmento la posición de la primera palabra etiquetada.

Veamos estas funciones -

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

Guarde estas funciones en un archivo de Python en su directorio local donde está instalado Python o Anaconda y ejecútelo. Lo he guardado comoverbcorrect.py.

Ahora, llamemos verbs() función en un POS etiquetado is you fine trozo -

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

Salida

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

Eliminando la voz pasiva de las frases

Otra tarea útil es eliminar la voz pasiva de las frases. Esto se puede hacer con la ayuda de intercambiar las palabras alrededor de un verbo. Por ejemplo,‘the tutorial was great’ se puede transformar en ‘the great tutorial’.

Ejemplo

Para lograr esto, estamos definiendo una función llamada eliminate_passive()que intercambiará el lado derecho del fragmento con el lado izquierdo usando el verbo como punto de pivote. Para encontrar el verbo pivotar, también usará elindex_chunk() función definida anteriormente.

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]

Ahora, llamemos eliminate_passive() función en un POS etiquetado the tutorial was great trozo -

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

Salida

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

Intercambio de cardenales sustantivos

Como sabemos, una palabra cardinal como 5 se etiqueta como CD en un fragmento. Estas palabras cardinales suelen aparecer antes o después de un sustantivo, pero para fines de normalización es útil colocarlas siempre antes del sustantivo. Por ejemplo, la fechaJanuary 5 Se puede escribir como 5 January. Entendamos con el siguiente ejemplo.

Ejemplo

Para lograr esto, estamos definiendo una función llamada swapping_cardinals()que cambiará cualquier cardenal que ocurra inmediatamente después de un sustantivo con el sustantivo. Con esto, el cardenal aparecerá inmediatamente antes del sustantivo. Para hacer una comparación de igualdad con la etiqueta dada, usa una función auxiliar que nombramos comotag_eql().

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

Ahora 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

Ahora, llamemos swapping_cardinals() funcionar en una cita “January 5” -

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

Salida

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