Saltar al contenido

¿Cómo obtener el árbol de dependencias con spaCy?

Posterior a de nuestra extensa búsqueda de datos dimos con la respuesta este apuro que tienen ciertos lectores. Te dejamos la solución y deseamos que te resulte de gran ayuda.

Solución:

En caso de que alguien quiera ver fácilmente el árbol de dependencias producido por spacy, una solución sería convertirlo en un nltk.tree.Tree y usa el nltk.tree.Tree.pretty_print método. Aquí hay un ejemplo:

import spacy
from nltk import Tree


en_nlp = spacy.load('en')

doc = en_nlp("The quick brown fox jumps over the lazy dog.")

def to_nltk_tree(node):
    if node.n_lefts + node.n_rights > 0:
        return Tree(node.orth_, [to_nltk_tree(child) for child in node.children])
    else:
        return node.orth_


[to_nltk_tree(sent.root).pretty_print() for sent in doc.sents]

Producción:

                jumps                  
  ________________|____________         
 |    |     |     |    |      over     
 |    |     |     |    |       |        
 |    |     |     |    |      dog      
 |    |     |     |    |    ___|____    
The quick brown  fox   .  the      lazy

Editar: Para cambiar la representación del token, puede hacer esto:

def tok_format(tok):
    return "_".join([tok.orth_, tok.tag_])


def to_nltk_tree(node):
    if node.n_lefts + node.n_rights > 0:
        return Tree(tok_format(node), [to_nltk_tree(child) for child in node.children])
    else:
        return tok_format(node)

Lo que resulta en:

                         jumps_VBZ                           
   __________________________|___________________             
  |       |        |         |      |         over_IN        
  |       |        |         |      |            |            
  |       |        |         |      |          dog_NN        
  |       |        |         |      |     _______|_______     
The_DT quick_JJ brown_JJ   fox_NN  ._. the_DT         lazy_JJ

El árbol no es un objeto en sí mismo; simplemente navega a través de las relaciones entre tokens. Es por eso que los documentos hablan de navegar por el árbol, pero no de ‘obtenerlo’.

Primero, analicemos un poco de texto para obtener una Doc objeto:

>>> import spacy
>>> nlp = spacy.load('en_core_web_sm')
>>> doc = nlp('First, I wrote some sentences. Then spaCy parsed them. Hooray!')

doc es un Sequence de Token objetos:

>>> doc[0]
First
>>> doc[1]
,
>>> doc[2]
I
>>> doc[3]
wrote

Pero no tiene un solo token raíz. Analizamos un texto compuesto por tres oraciones, por lo que hay tres árboles distintos, cada uno con su propia raíz. Si queremos comenzar nuestro análisis desde la raíz de cada oración, ayudará obtener las oraciones como objetos distintos, primero. Afortunadamente, doc nos las expone a través de la .sents propiedad:

>>> sentences = list(doc.sents)
>>> for sentence in sentences:
...     print(sentence)
... 
First, I wrote some sentences.
Then spaCy parsed them.
Hooray!

Cada una de estas oraciones es una Span con un .root propiedad que apunta a su token raíz. Por lo general, el token raíz será el verbo principal de la oración (aunque esto puede no ser así). true para estructuras de oraciones inusuales, como oraciones sin verbo):

>>> for sentence in sentences:
...     print(sentence.root)
... 
wrote
parsed
Hooray

Con el token raíz encontrado, podemos navegar hacia abajo en el árbol a través de la .children propiedad de cada token. Por ejemplo, busquemos el sujeto y el objeto del verbo en la primera oración. los .dep_ la propiedad de cada token hijo describe su relación con su padre; por ejemplo un dep_ de 'nsubj' significa que un token es el sujeto nominal de su padre.

>>> root_token = sentences[0].root
>>> for child in root_token.children:
...     if child.dep_ == 'nsubj':
...         subj = child
...     if child.dep_ == 'dobj':
...         obj = child
... 
>>> subj
I
>>> obj
sentences

También podemos seguir bajando por el árbol viendo uno de los hijos de estos tokens:

>>> list(obj.children)
[some]

Por lo tanto, con las propiedades anteriores, puede navegar por todo el árbol. Si desea visualizar algunos árboles de dependencia para oraciones de ejemplo que lo ayuden a comprender la estructura, le recomiendo jugar con displaCy.

Puede usar la biblioteca a continuación para ver su árbol de dependencias, ¡lo encontró extremadamente útil!

import spacy
from spacy import displacy

nlp = spacy.load('en')
doc = nlp(u'This is a sentence.')
displacy.serve(doc, style='dep')

Puede abrirlo con su navegador, y se ve así:
salida de servicio de desplazamiento

Para generar un archivo SVG:

from pathlib import Path

output_path = Path("yourpath/.svg")
svg = displacy.render(doc, style='dep')
with output_path.open("w", encoding="utf-8") as fh:
    fh.write(svg)

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *