Boîte à outils en langage naturel - Transformer les arbres

Voici les deux raisons de transformer les arbres -

  • Pour modifier l'arborescence d'analyse approfondie et
  • Pour aplatir les arbres d'analyse profonds

Conversion d'un arbre ou d'un sous-arbre en phrase

La première recette que nous allons discuter ici est de reconvertir un arbre ou un sous-arbre en une phrase ou une chaîne de blocs. C'est très simple, voyons dans l'exemple suivant -

Exemple

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

Production

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

Aplatissement profond des arbres

Les arbres profonds de phrases imbriquées ne peuvent pas être utilisés pour entraîner un morceau, nous devons donc les aplatir avant de les utiliser. Dans l'exemple suivant, nous allons utiliser la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de latreebank corpus.

Exemple

Pour y parvenir, nous définissons une fonction nommée deeptree_flat()cela prendra un seul arbre et renverra un nouvel arbre qui ne conserve que les arbres de niveau le plus bas. Afin de faire la plupart du travail, il utilise une fonction d'assistance que nous avons nomméechildtree_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]))

Maintenant, appelons deeptree_flat() fonction sur la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, treebankcorpus. Nous avons enregistré ces fonctions dans un fichier nommé deeptree.py.

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

Production

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')]), ('.', '.')])

Construire un arbre peu profond

Dans la section précédente, nous aplatissons un arbre profond de phrases imbriquées en ne conservant que les sous-arbres de niveau le plus bas. Dans cette section, nous allons conserver uniquement les sous-arbres de plus haut niveau c'est-à-dire pour construire l'arbre peu profond. Dans l'exemple suivant, nous allons utiliser la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, de latreebank corpus.

Exemple

Pour y parvenir, nous définissons une fonction nommée tree_shallow() cela éliminera tous les sous-arbres imbriqués en ne conservant que les étiquettes de sous-arbre supérieures.

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)

Maintenant, appelons tree_shallow()fonction le 3 ème phrase analysable, qui est l' arbre profond des phrases imbriquées, de latreebankcorpus. Nous avons enregistré ces fonctions dans un fichier nommé shallowtree.py.

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

Production

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')]), ('.', '.')])

Nous pouvons voir la différence en obtenant la hauteur des arbres -

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

Production

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

Production

9

Conversion d'étiquettes d'arbre

Dans les arbres d'analyse, il existe une variété de Treetypes d'étiquettes qui ne sont pas présents dans les arborescences de blocs. Mais tout en utilisant l'arborescence d'analyse pour former un bloc, nous aimerions réduire cette variété en convertissant certaines des étiquettes d'arbre en types d'étiquettes plus courants. Par exemple, nous avons deux sous-arbres NP alternatifs, à savoir NP-SBL et NP-TMP. Nous pouvons les convertir tous les deux en NP. Voyons comment le faire dans l'exemple suivant.

Exemple

Pour y parvenir, nous définissons une fonction nommée tree_convert() qui prend les deux arguments suivants -

  • Arbre à convertir
  • Un mappage de conversion d'étiquette

Cette fonction renverra une nouvelle arborescence avec toutes les étiquettes correspondantes remplacées en fonction des valeurs du mappage.

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)

Maintenant, appelons tree_convert() fonction sur la 3e phrase analysée, qui est un arbre profond de phrases imbriquées, treebankcorpus. Nous avons enregistré ces fonctions dans un fichier nomméconverttree.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)

Production

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('.', ['.'])])