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