Using Spacy in Python To Extract Named Entities in Spanish

The Spacy Small Language model has some difficulty with contemporary news text that are not either Eurocentric or US based. Likely, this lack of accuracy with contemporary figures owes in part to a less thorough scrape of Wikipedia and relative changes that have taken place in Mexico, Bolivia and other countries with highly variant dialects of Spanish in LATAM since 2018. Regardless, that dataset can and does garner some results for the purpose of this exercise. This means that we can toy a bit around with some publicly available data.

Entity Hash For Spanish Text

In this informal exercise, we will try to hack our way through some Spanish text. Specifically, making use of NER capacities that are sourced from public data – no rule based analysis – with some functions I find useful for visualizing Named Entities in Spanish text. We have prepared a Spanish news text on the topic of ‘violence’ or violent crime sourced from publicly available Spanish news content in Mexico.

Using spacy, you can hash the entities extracted from a corpus. We will use the lighter Spanish language model from Spacy’s natural language toolkit. This language model is a statistical description of Wikipedia’s Spanish corpus which is likely slanted towards White Hispanic speech so beware it’s bias.

First, import the libraries:

import spacy
import spacy.attrs
nlp = spacy.load('es_core_news_sm')

With the libraries in place, we can import the module ‘org_per’. This module is referencing this Github repo.

The work of identifying distinct entities is done in a function that filters for Geographical entities and People. Both of these tags are labeled as ‘GEO’ and ‘PER’, respectively in spacy’s data.

The variable ‘raw_corpus‘ is the argument you provide, which should be some Spanish text data. If you don’t have any, visit the repository and load that file object.

import org_per
raw_corpus = open('corpus_es_noticias_mx.txt','r', encoding='utf-8').read().split("\n")[1:]
entities = org_per.sacalasentidades(raw_corpus)
 
# use list of entities that are ORG or PER and count up
# each invidividual token.     

tokensdictionary = org_per.map_entities(entities) 

As noted before, the text has its origins in Wikipedia. This means that newer more contemporary types of text may not be sufficiently well covered – breadth doesn’t imply depth in analysis because stochastic models rely on some passing resemblance with data that may not ever have been seen.

Anecdotally, over a small corpus, we see performance below 80 percent accuracy for this language model. Presumably, a larger sampling of Wikipedia ES data will perform higher, but certain trends in contemporary news text makes this expectation necessary to temper.

The output returned from running `org_per.map_entities(entities)` will look like this:

{"Bill Clinton": 123,
"Kenneth Starr" : 12,
}

The actual hashing is a simple enough method involving placing NER text with its frequency count as a value in a dictionary. Within your dictionary, you may get parses of Named Entities that are incorrect. That is to say, they are not properly delimited because the Named Entity Language Model does not have an example of your parse. For instance, Lopez Obrador – the current president of Mexico – is not easily recognized as ‘PER’.

Accuracy

This is measured very simply through tabulating how much you agree with the returned Named Entities. The difference between expected and returned values is your error rate. More on accuracy metrics next post.

Introducción a Python

logotipo de Python

Python es un lenguaje de programación bastante flexible y veloz cuando se
considera que es un lenguaje de alto nivel. En este breve resumen del idioma se presenta un ejercicio que abre un archivo. Esta tarea es casi rutinaria en todo trabajo complejo.

Ahora, si buscas un ejercicio más avanzado o uno que simplemente abarca un tema en particular sugiero este enlace . También tengo un proyecto donde identifico las entidades en un texto pero la documentación esta en ingles.

“Los lenguajes de programación de alto nivel se caracterizan porque su estructura semántica es muy similar a la forma como escriben los humanos, lo que permite codificar los algoritmos de manera más natural, en lugar de codificarlos en el lenguaje binario de las máquinas, o a nivel de lenguaje ensamblador.”

UNAM, F. J. (2004). Enciclopedia del lenguaje C. México: Alfaomega/RaMa.

Básicamente quiere decir que Python simplifica operaciones que usan más líneas de código en otros lenguajes de programación dentro de un formato más compacto y amigable. En parte, esto limita la relevancia del idioma para ciertas aplicaciones industriales pero esto no es tan relevante para un programador principiante o avanzado con metas dentro del campo de PLN o Inteligencia Artificial.

Lo importante es que rápidamente puedes llevar a cabo una tarea sobre alguna tarea que sería imposible completar a mano.

Modulos/Librerias de Python

Un modulo o librería en Python es una base de código ya hecho (quizás ya incluida como parte de la instalación de la version de Python) que permite que el usuario lleve a cabo ciertas tareas.

Un módulo es un objeto de Python con atributos con nombres arbitrarios que puede enlazar y hacer referencia.

COVANTEC

El término ‘librería’ o modulo existe para todo idioma de programación.

Este programa usa una sentencia que invoca otro modulo: ‘import’ X es
el patrón. Por ejemplo, import csv implica que el usuario busca importar el modulo de csv que se especializa en abrir o leer un archivo csv.

import csv
#csv una libreria para textos delimitados por ','

Flexibilidad

Bastante se puede llevar acabo con las librerías ya instaladas en cualquier version de Python descargada. Es mas, tambien es posible (pero no recomendable a largo plazo) usar Python sin la estructura de orientación de objeto de manera profunda.

Es decir que no se tienen que definir clases o metodos muy sofisticados y igual se puede derivar un ben uso del idioma.

Es decir que se pueden utilizar los módulos de Python como si fuese un script como el idioma de BASH. Si ninguna de estas oraciones tiene mucho sentido por la falta de contexto, está bien.

Por ahora, es suficiente saber que Python es bastante flexible y fácil de entender. Unas cuantas líneas de código pueden llevar una tarea fácil (pero repetitiva) a una adecuada resolución.

Interpretado – no compilado

Python es un idioma que sin un compilador puede correr y generar un análisis o resultado de algún tipo con mucha facilidad. Por ejemplo, esta interacción demuestra una operación de aritmética llevandose a cabo.

2 + 2 en Python:

Python en Anaconda: Una sesión interactiva donde un programador corre una secuencia de comandos para obtener su resultado final.

Finalmente, recomiendo el uso de Anaconda-Spyder ya que cuenta con mucha documentación y librerías

Spyder es un enviro de desarrollo que esta equipado con los módulos necesarios para un analista de datos junto con buena documentación y accesos a nueva librerías. El grupo de Anaconda actualiza un repositorio con las librerías mas actualizadas y relevantes.

Anaconda está disponible aquí hasta mero abajo de la página.

Sintaxis abrir y cerrar un archivo en Python

Una tarea simple como abrir un archivo es posible con una sola linea de codigo o varias dependiendo en como se guste organizar el codigo.

#NO ES CODIGO: se agrega documentacion o comentarios
file = open('ejemplo.txt', 'r')

#puedes acceder methodos del objeto 'file' con '.'
file.read()

Alternativamente, la sintaxis permite:

file = open('ejemplo.txt', 'r').read()

Tambien existe la posibilidad de agregar argumentos que lean bien el tipo de texto que se busque leer ya que hay codecs distintos de acuerdo con los caracteres de un idioma. Nota que no hemos invocado ningun tipo de modulo para estas operaciones.

file = open('ejemplo.txt', 'r', encoding='utf-8').read()

Importando librerías ya preinstaladas: regular expressions

Una librería ya instalada en Python es la de ‘regular expressions‘ denominada simplemente “re” y que se importa de la siguiente manera.

import re 

La librería puede invocar el metodo de substitución com un atributo. Es decir con el símbolo ‘.’ adjunto al modulo ‘re’.

objeto = re.sub('abc', 'cba', 'este es el texto que se manipula abc')

El ejemplo tiene como primer argumento de re.sub( …) a el hilario que se buscar reemplazar y el segundo argumento con que se busca reemplazar. Finalmente, el tercer argumento hace referencia al texto que buscar manipular: ‘este es el texto que se manipula abc’.