Skip to content

Latest commit

 

History

History
434 lines (282 loc) · 13.5 KB

chapter2.md

File metadata and controls

434 lines (282 loc) · 13.5 KB
title description prev next type id
Capítulo 2: Análisis de datos a gran escala con spaCy
En este capítulo usarás tus nuevas habilidades para extraer información específica de grandes volúmenes de texto. Aprenderás a sacarle el mayor provecho a las estructuras de datos de spaCy y cómo combinar los enfoques estadísticos y basados en reglas de manera efectiva para el análisis de texto.
/chapter1
/chapter3
chapter
2

Parte 1

  • Busca el string "cat" en nlp.vocab.strings para obtener el hash.
  • Busca el hash para obtener el string.
  • Puedes usar el string store en nlp.vocab.strings como un diccionario normal de Python. Por ejemplo, nlp.vocab.strings["unicornio"] devolverá el hash y buscar el hash devolverá el string "unicornio".

Parte 2

  • Busca la etiqueta del string "PER" en nlp.vocab.strings para obtener el hash.
  • Busca el hash para obtener el string.
  • Puedes usar el string store en nlp.vocab.strings como un diccionario de Python normal. Por ejemplo, nlp.vocab.strings["unicornio"] devolverá el hash y buscar el hash devolverá el string "unicornio".

¿Porqué devuelve un error este código?

import spacy

# Crea un objeto nlp de español y uno de alemán
nlp = spacy.blank("es")
nlp_de = spacy.blank("de")

# Obtén el ID para el string "Bowie"
bowie_id = nlp.vocab.strings["Bowie"]
print(bowie_id)

# Busca el ID de "Bowie" en el vocabulario
print(nlp_de.vocab.strings[bowie_id])

Los hashes no pueden ser revertidos. Para prevenir este problema añade la palabra al nuevo vocabulario. Para hacer esto, procesa el texto, busca el string, o usa el mismo vocabulario para resolver el hash de regreso a string.

Cualquier string puede ser convertido a un hash.

El nombre de variable nlp es solo una convención. Si el código usara el nombre de variable nlp en vez de nlp_de se sobrescribiría el objeto nlp existente, incluyendo el vocabulario.

¡Creemos algunos objetos Doc desde cero!

Parte 1

  • Importa el Doc desde spacy.tokens.
  • Crea un Doc a partir de words y spaces. ¡No te olvides de pasar el vocabulario!

La clase Doc recibe 3 argumentos: el vocabulario compartido (generalmente nlp.vocab), una lista de words y una lista de spaces, (valores booleanos que indican si una palabra está seguida de un espacio o no).

Parte 2

  • Importa el Doc desde spacy.tokens.
  • Crea un Doc a partir de words y spaces. ¡No te olvides de pasar el vocabulario!

Mira cada palabra en el texto deseado y revisa si está seguido por un espacio. Si lo está, el valor del espacio debería ser True. Si no, debería ser False.

Parte 3

  • Importa el Doc desde spacy.tokens.
  • Completa los words y los spaces para que coincidan con el texto deseado y crea un doc.

Presta atención a los tokens individuales. Para ver cómo se tokeniza un string normalmente en spaCy puedes probarlo e imprimir los tokens de nlp("¡¿En serio?!").

En este ejercicio crearás los objetos Doc y Span manualmente y actualizarás las entidades nombradas - igual que lo hace spaCy detrás de cámaras. Un objeto nlp compartido ya fue creado.

  • Importa las clases Doc y Span desde spacy.tokens.
  • Usa la clase Doc directamente para crear un doc a partir de palabras y espacios.
  • Crea un Span para "David Bowie" desde el doc y asígnalo al label "PER".
  • Sobrescribe los doc.ents con una lista de una entidad, el Span "David Bowie".
  • El Doc es inicializado con tres argumentos: el vocabulario compartido, e.g. nlp.vocab, una lista de palabras y una lista de valores booleanos que indican si una palabra está seguida por un espacio.
  • La clase Span recibe cuatro argumentos: el doc de referencia, el índice de inicio del token, el índice del final del token y un label opcional.
  • La propiedad doc.ents es escribible así que puedes asignarle cualquier iterable que consista de objetos Span.

El código en este ejemplo está intentando analizar un texto y recoger todos los nombres propios que están seguidos por un verbo.

import spacy

nlp = spacy.load("es_core_news_sm")
doc = nlp("Por Berlín fluye el río Esprea.")

# Obtén todos los tokens y los part-of-speech tags
token_texts = [token.text for token in doc]
pos_tags = [token.pos_ for token in doc]

for index, pos in enumerate(pos_tags):
    # Revisa si el token actual es un nombre propio
    if pos == "PROPN":
        # Revisa si el token siguiente es un verbo
        if pos_tags[index + 1] == "VERB":
            result = token_texts[index]
            print("Encontré un nombre propio antes de un verbo:", result)

Parte 1

¿Por qué está mal este código?

No debería ser necesario convertir strings de regreso a objetos Token. Deberías evitar convertir tokens a strings si todavía necesitas acceder a sus atributos y relaciones.

Siempre convierte los resultados a strings lo más tarde posible e intenta usar los atributos nativos de los tokens para mantener la consistencia.

El atributo .pos_ devuelve el part-of-speech tag grueso y PROPN es la etiqueta correcta para revisar los nombres propios.

Parte 2

  • Reescribe el código y usa los atributos nativos de los tokens en vez de listas de token_texts y pos_tags.
  • Has un loop sobre cada token en el doc y revisa el atributo token.pos_.
  • Usa doc[token.i + 1] para revisar el token siguiente y su atributo .pos_.
  • Si encuentras un nombre propio antes de un verbo imprime en pantalla su token.text.
  • Quita los token_texts y pos_tags – ¡No necesitamos compilar listas de strings por adelantado!
  • En vez de iterar sobre los pos_tags, has un loop sobre cada token en el doc y revisa el atributo token.pos_.
  • Para comprobar si el próximo token es un verbo, mira el doc[token.i + 1].pos_.

En este ejercicio usarás un modelo de español más grande, que incluye al rededor de 20.000 word vectors. El modelo ya está pre-instalado.

  • Carga el modelo mediano "es_core_news_md" con word vectors.
  • Imprime en pantalla el vector de "banano" usando el atributo token.vector.
  • Para cargar el modelo estadístico llama a spacy.load con su nombre en string.
  • Para acceder al token en el doc puedes usar su índice. Por ejemplo, doc[4].

En este ejercicio usarás el método similarity de spaCy para comparar objetos Doc, Token y Span y obtener puntajes de similitud.

Parte 1

  • Usa el método doc.similarity para comparar el doc1 con el doc2 e imprime el resultado en pantalla.
  • El método doc.similarity recibe un argumento: el otro objeto con el que debe comparar el objeto actual.

Parte 2

  • Usa el método token.similarity para comparar el token1 al token2 e imprime el resultado en pantalla.
  • El método token.similarity recibe un argumento: el otro objeto con el que debe comparar el objeto actual.

Parte 3

  • Crea spans para "restaurante genial"/ "bar muy divertido".
  • Usa span.similarity para compararlos e imprime el resultado en pantalla.

¿Por qué este patrón no encuentra los tokens "Silicon Valley" en el doc?

pattern = [{"LOWER": "silicon"}, {"TEXT": " "}, {"LOWER": "valley"}]
doc = nlp("¿Por qué Silicon Valley necesita miles de astrofísicos?")

El atributo LOWER en el patrón describe a los tokens que pueden ser encontrados con el valor dado en minúsculas. Así, {"LOWER": "valley"} encontrará tokens como "Valley", "VALLEY", "valley", etc.

El tokenizer se encarga de hacer las separaciones por los espacios en blanco y cada diccionario en el patrón describe un token.

Por defecto, todos los tokens descritos por un patrón van a ser encontrados una vez. Los operadores solo tienen que ser añadidos para cambiar este comportamiento - por ejemplo, para encontrar cero o más veces.

Los dos patrones en este ejercicio contienen errores y no van a tener los resultados esperados. ¿Puedes arreglarlos? Si te atascas intenta imprimir en pantalla los tokens en el doc para ver cómo se va a dividir el texto y ajusta el patrón para que cada diccionario represente un token.

  • Edita el pattern1 para que encuentre correctamente todas las menciones de una cantidad de tiempo, más un sustantivo.
  • Edita el pattern2 para que encuentre correctamente todas las menciones de "pac-man", sin importar si son minúsculas o mayúsculas, más una palabra en mayúsculas.
  • Procesa los strings que deben ser encontrados con el objeto nlp - for ejemplo, [token.text for token in nlp("pac-man Live")].
  • Inspecciona los tokens y asegúrate de que cada diccionario en el patrón describa correctamente a un token.

A veces es más eficiente buscar los strings exactos en vez de escribir los patrones describiendo los tokens individuales. Esto es especialmente cierto para cosas que tienen categorías finitas - como todos los países del mundo. Aquí tenemos una lista de países, así que usémoslos como base para nuestro script para extraer información. La lista de nombres en strings está disponible en la variable COUNTRIES.

  • Importa el PhraseMatcher e inicialízalo con el vocab compartido como la variable matcher.
  • Añade los patrones de frases y llama al matcher sobre el doc.

El vocab compartido está disponible como nlp.vocab.

En el ejercicio anterior escribiste un script usando el PhraseMatcher de spaCy para encontrar nombres de países en un texto. Usemos ese buscador de países en un texto más largo. Analiza la sintaxis y actualiza las entidades del documento con los países resultantes.

  • Itera sobre los resultados y crea un Span con el label "LOC" (Nombres de ubicaciones definidas política o geográficamente).
  • Sobrescribe las entidades en el doc.ents y añade el span resultante.
  • Obtén el token cabeza de la raíz del span.
  • Imprime en pantalla el texto del token cabeza y el span.
  • Recuerda que el texto está disponible como la variable text.
  • El token raíz del span está disponible como span.root. El token cabeza está disponible a través del atributo token.head.