Kit de herramientas de lenguaje natural: transformación de árboles

Las siguientes son las dos razones para transformar los árboles:

  • Para modificar el árbol de análisis profundo y
  • Para aplanar árboles de análisis profundo

Conversión de árbol o subárbol en oración

La primera receta que vamos a discutir aquí es convertir un árbol o subárbol de nuevo en una oración o cadena de bloques. Esto es muy simple, veamos en el siguiente ejemplo:

Ejemplo

from nltk.corpus import treebank_chunk
tree = treebank_chunk.chunked_sents()[2]
' '.join([w for w, t in tree.leaves()])

Salida

'Rudolph Agnew , 55 years old and former chairman of Consolidated Gold Fields
PLC , was named a nonexecutive director of this British industrial
conglomerate .'

Aplanamiento profundo de árboles

Los árboles profundos de frases anidadas no se pueden usar para entrenar un fragmento, por lo tanto, debemos aplanarlos antes de usarlos. En el siguiente ejemplo, usaremos la tercera oración analizada, que es un árbol profundo de frases anidadas, de latreebank cuerpo.

Ejemplo

Para lograr esto, estamos definiendo una función llamada deeptree_flat()que tomará un solo árbol y devolverá un nuevo árbol que mantiene solo los árboles del nivel más bajo. Para hacer la mayor parte del trabajo, utiliza una función auxiliar que nombramos comochildtree_flat().

from nltk.tree import Tree
def childtree_flat(trees):
   children = []
   for t in trees:
      if t.height() < 3:
         children.extend(t.pos())
      elif t.height() == 3:
         children.append(Tree(t.label(), t.pos()))
      else:
         children.extend(flatten_childtrees([c for c in t]))
   return children
def deeptree_flat(tree):
   return Tree(tree.label(), flatten_childtrees([c for c in tree]))

Ahora, llamemos deeptree_flat() función en la tercera oración analizada, que es un árbol profundo de frases anidadas, de la treebankcuerpo. Guardamos estas funciones en un archivo llamado deeptree.py.

from deeptree import deeptree_flat
from nltk.corpus import treebank
deeptree_flat(treebank.parsed_sents()[2])

Salida

Tree('S', [Tree('NP', [('Rudolph', 'NNP'), ('Agnew', 'NNP')]),
(',', ','), Tree('NP', [('55', 'CD'), 
('years', 'NNS')]), ('old', 'JJ'), ('and', 'CC'),
Tree('NP', [('former', 'JJ'), 
('chairman', 'NN')]), ('of', 'IN'), Tree('NP', [('Consolidated', 'NNP'), 
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 
'NNP')]), (',', ','), ('was', 'VBD'), 
('named', 'VBN'), Tree('NP-SBJ', [('*-1', '-NONE-')]), 
Tree('NP', [('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN')]),
('of', 'IN'), Tree('NP', 
[('this', 'DT'), ('British', 'JJ'), 
('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])

Construcción de árbol poco profundo

En la sección anterior, aplanamos un árbol profundo de frases anidadas manteniendo solo los subárboles de nivel más bajo. En esta sección, vamos a mantener solo los subárboles de más alto nivel, es decir, para construir el árbol poco profundo. En el siguiente ejemplo usaremos la tercera oración analizada, que es un árbol profundo de frases anidadas, de latreebank cuerpo.

Ejemplo

Para lograr esto, estamos definiendo una función llamada tree_shallow() que eliminará todos los subárboles anidados manteniendo solo las etiquetas del subárbol superior.

from nltk.tree import Tree
def tree_shallow(tree):
   children = []
   for t in tree:
      if t.height() < 3:
         children.extend(t.pos())
      else:
         children.append(Tree(t.label(), t.pos()))
   return Tree(tree.label(), children)

Ahora, llamemos tree_shallow()función el 3 rd frase analizada, que es profunda árbol de frases anidadas, desde eltreebankcuerpo. Guardamos estas funciones en un archivo llamado shallowtree.py.

from shallowtree import shallow_tree
from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2])

Salida

Tree('S', [Tree('NP-SBJ-1', [('Rudolph', 'NNP'), ('Agnew', 'NNP'), (',', ','), 
('55', 'CD'), ('years', 'NNS'), ('old', 'JJ'), ('and', 'CC'), 
('former', 'JJ'), ('chairman', 'NN'), ('of', 'IN'), ('Consolidated', 'NNP'), 
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 'NNP'), (',', ',')]), 
Tree('VP', [('was', 'VBD'), ('named', 'VBN'), ('*-1', '-NONE-'), ('a', 'DT'), 
('nonexecutive', 'JJ'), ('director', 'NN'), ('of', 'IN'), ('this', 'DT'), 
('British', 'JJ'), ('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])

Podemos ver la diferencia con la ayuda de obtener la altura de los árboles:

from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2]).height()

Salida

3
from nltk.corpus import treebank
treebank.parsed_sents()[2].height()

Salida

9

Conversión de etiquetas de árbol

En los árboles de análisis hay variedad de Treetipos de etiquetas que no están presentes en árboles de trozos. Pero mientras usamos el árbol de análisis para entrenar un fragmento, nos gustaría reducir esta variedad convirtiendo algunas de las etiquetas de árbol en tipos de etiquetas más comunes. Por ejemplo, tenemos dos subárboles NP alternativos, a saber, NP-SBL y NP-TMP. Podemos convertir ambos en NP. Veamos cómo hacerlo en el siguiente ejemplo.

Ejemplo

Para lograr esto, estamos definiendo una función llamada tree_convert() que toma los siguientes dos argumentos:

  • Árbol para convertir
  • Un mapeo de conversión de etiquetas

Esta función devolverá un nuevo árbol con todas las etiquetas coincidentes reemplazadas según los valores del mapeo.

from nltk.tree import Tree
def tree_convert(tree, mapping):
   children = []
   for t in tree:
      if isinstance(t, Tree):
         children.append(convert_tree_labels(t, mapping))
      else:
         children.append(t)
   label = mapping.get(tree.label(), tree.label())
   return Tree(label, children)

Ahora, llamemos tree_convert() función en la tercera oración analizada, que es un árbol profundo de frases anidadas, de la treebankcuerpo. Guardamos estas funciones en un archivo llamadoconverttree.py.

from converttree import tree_convert
from nltk.corpus import treebank
mapping = {'NP-SBJ': 'NP', 'NP-TMP': 'NP'}
convert_tree_labels(treebank.parsed_sents()[2], mapping)

Salida

Tree('S', [Tree('NP-SBJ-1', [Tree('NP', [Tree('NNP', ['Rudolph']), 
Tree('NNP', ['Agnew'])]), Tree(',', [',']), 
Tree('UCP', [Tree('ADJP', [Tree('NP', [Tree('CD', ['55']), 
Tree('NNS', ['years'])]), 
Tree('JJ', ['old'])]), Tree('CC', ['and']), 
Tree('NP', [Tree('NP', [Tree('JJ', ['former']), 
Tree('NN', ['chairman'])]), Tree('PP', [Tree('IN', ['of']), 
Tree('NP', [Tree('NNP', ['Consolidated']), 
Tree('NNP', ['Gold']), Tree('NNP', ['Fields']), 
Tree('NNP', ['PLC'])])])])]), Tree(',', [','])]), 
Tree('VP', [Tree('VBD', ['was']),Tree('VP', [Tree('VBN', ['named']), 
Tree('S', [Tree('NP', [Tree('-NONE-', ['*-1'])]), 
Tree('NP-PRD', [Tree('NP', [Tree('DT', ['a']), 
Tree('JJ', ['nonexecutive']), Tree('NN', ['director'])]), 
Tree('PP', [Tree('IN', ['of']), Tree('NP', 
[Tree('DT', ['this']), Tree('JJ', ['British']), Tree('JJ', ['industrial']), 
Tree('NN', ['conglomerate'])])])])])])]), Tree('.', ['.'])])