Python para PNL: tokenización, derivación y lematización con la biblioteca SpaCy

P

En el artículo anterior, comenzamos nuestra discusión sobre cómo hacer procesamiento de lenguaje natural con Python. Vimos cómo leer y escribir archivos de texto y PDF. En este artículo, comenzaremos a trabajar con espacio biblioteca para realizar algunas tareas más básicas de PNL, como tokenización, derivación y lematización.

Introducción a SpaCy

La biblioteca spaCy es una de las bibliotecas NLP más populares junto con NLTK. La diferencia básica entre las dos bibliotecas es el hecho de que NLTK contiene una amplia variedad de algoritmos para resolver un problema, mientras que spaCy contiene solo uno, pero el mejor algoritmo para resolver un problema.

NLTK se lanzó en 2001, mientras que spaCy es relativamente nuevo y se desarrolló en 2015. En esta serie de artículos sobre PNL, nos ocuparemos principalmente de spaCy, debido a su naturaleza de vanguardia. Sin embargo, también tocaremos NLTK cuando sea más fácil realizar una tarea usando NLTK en lugar de spaCy.

Instalación de spaCy

Si usa el instalador de pip para instalar sus bibliotecas de Python, vaya a la línea de comando y ejecute la siguiente declaración:

$ pip install -U spacy

De lo contrario, si está utilizando Anaconda, debe ejecutar el siguiente comando en el indicador de Anaconda:

$ conda install -c conda-forge spacy

Una vez que descargue e instale spaCy, el siguiente paso es descargar el modelo de idioma. Usaremos el modelo de idioma inglés. El modelo de lenguaje se utiliza para realizar una variedad de tareas de PNL, que veremos en una sección posterior.

El siguiente comando descarga el modelo de lenguaje:

$ python -m spacy download en

Funcionalidad básica

Antes de profundizar en las diferentes funciones de SpaCy, veamos brevemente cómo trabajar con él.

Como primer paso, debe importar el spacy biblioteca de la siguiente manera:

import spacy

A continuación, necesitamos cargar el modelo de lenguaje spaCy.

sp = spacy.load('en_core_web_sm')

En el script de arriba usamos el load función de la spacy biblioteca para cargar el modelo básico del idioma inglés. El modelo se almacena en el sp variable.

Creemos ahora un pequeño documento usando este modelo. Un documento puede ser una oración o un grupo de oraciones y puede tener una extensión ilimitada. La siguiente secuencia de comandos crea un documento spaCy simple.

sentence = sp(u'Manchester United is looking to sign a forward for $90 million')

SpaCy divide automáticamente su documento en tokens cuando se crea un documento utilizando el modelo.

Una ficha simplemente se refiere a una parte individual de una oración que tiene algún valor semántico. Veamos qué tokens tenemos en nuestro documento:

for word in sentence:
    print(word.text)

La salida del script anterior se ve así:

Manchester
United
is
looking
to
sign
a
forward
for
$
90
million

Puede ver que tenemos los siguientes tokens en nuestro documento. También podemos ver el partes de la oración de cada uno de estos tokens usando el .pos_ atributo que se muestra a continuación:

for word in sentence:
    print(word.text,  word.pos_)

Salida:

Manchester PROPN
United PROPN
is VERB
looking VERB
to PART
sign VERB
a DET
forward NOUN
for ADP
$ SYM
90 NUM
million NUM

Puede ver que a cada palabra o símbolo de nuestra oración se le ha asignado una parte del discurso. Por ejemplo, “Manchester” ha sido etiquetado como un nombre propio, “Looking” ha sido etiquetado como un verbo, y así sucesivamente.

Finalmente, además de las partes del discurso, también podemos ver las dependencias.

Creemos otro documento:

sentence2 = sp(u"Manchester United isn't looking to sign any forward.")

Para el análisis de dependencias, el atributo dep_ se utiliza como se muestra a continuación:

for word in sentence2:
    print(word.text,  word.pos_, word.dep_)

La salida se ve así:

Manchester PROPN compound
United PROPN nsubj
is VERB aux
n't ADV neg
looking VERB ROOT
to PART aux
sign VERB xcomp
any DET advmod
forward ADV advmod
. PUNCT punct

En la salida, puede ver que spaCy es lo suficientemente inteligente como para encontrar la dependencia entre los tokens, por ejemplo, en la oración teníamos una palabra is'nt. El analizador de dependencias lo ha dividido en dos palabras y especifica que el n't es en realidad la negación de la palabra anterior.

Para obtener una comprensión detallada del análisis de dependencias, consulte Este artículo.

Además de imprimir las palabras, también puede imprimir frases de un documento.

document = sp(u'Hello from Pharos.sh. The site with the best Python Tutorials. What are you looking for?')

Ahora, podemos iterar a través de cada oración usando el siguiente script:

for sentence in document.sents:
    print(sentence)

La salida del script se ve así:

Hello from Pharos.sh.
The site with the best Python Tutorials.
What are you looking for?

También puede verificar si una oración comienza con un token en particular o no. Puede obtener tokens individuales usando un índice y los corchetes, como una matriz:

document[4]

En la secuencia de comandos anterior, buscamos la quinta palabra en el documento. Tenga en cuenta que el índice comienza desde cero y el período cuenta como un token. En la salida debería ver:

The

Ahora para ver si alguna oración en el documento comienza con The, podemos usar el is_sent_start atributo como se muestra a continuación:

document[4].is_sent_start

En la salida, verá True desde el token The se utiliza al comienzo de la segunda oración.

En esta sección, vimos algunas operaciones básicas de la biblioteca spaCy. Ahora profundicemos y veamos la tokenización, la derivación y la lematización en detalle.

Tokenización

Como se explicó anteriormente, la tokenización es el proceso de dividir un documento en palabras, signos de puntuación, dígitos numéricos, etc.

Veamos la tokenización de spaCy en detalle. Cree un nuevo documento usando el siguiente script:

sentence3 = sp(u'"They're leaving U.K. for U.S.A."')
print(sentence3)

Puede ver que la oración contiene comillas al principio y al final. También contiene signos de puntuación en las abreviaturas “Reino Unido” y “EE. UU.”

Veamos cómo spaCy tokeniza esta oración.

for word in sentence3:
    print(word.text)

Salida:

"
They
're
leaving
U.K.
for
U.S.A.
"

En la salida, puede ver que spaCy ha tokenizado las comillas dobles inicial y final. Sin embargo, es lo suficientemente inteligente como para no simbolizar el punto de puntuación utilizado entre las abreviaturas como Reino Unido y EE. UU.

Veamos otro ejemplo de tokenización:

sentence4 = sp(u"Hello, I am non-vegetarian, email me the menu at [email protected]")
print(sentence4)

Aquí, en la oración anterior, tenemos un guión en la palabra “no vegetariano” y en la dirección de correo electrónico. Veamos cómo spaCy tokenizará esto:

for word in sentence4:
    print(word.text)

Salida:

Hello
,
I
am
non
-
vegetarian
,
email
me
the
menu
at
[email protected]

Es evidente por el resultado que spaCy fue capaz de detectar el correo electrónico y no lo tokenizó a pesar de tener un “-“. Por otro lado, la palabra “no vegetariano” fue tokenizada.

Veamos ahora cómo podemos contar las palabras en el documento:

len(sentence4)

En la salida, verá 14, que es el número de tokens en el sentence4.

Detectando Entidades

Además de convertir los documentos en palabras, también puede encontrar si la palabra es una entidad como una empresa, lugar, edificio, moneda, institución, etc.

Veamos un ejemplo simple de reconocimiento de entidad con nombre:

sentence5 = sp(u'Manchester United is looking to sign Harry Kane for $90 million')  

Primero intentemos simplemente tokenizarlo:

for word in sentence5:
    print(word.text)

Salida:

Manchester
United
is
looking
to
sign
Harry
Kane
for
$
90
million

Sabemos que “Manchester United” es una sola palabra, por lo tanto, no debe dividirse en dos palabras. De manera similar, “Harry Kane” es el nombre de una persona y “$ 90 millones” es un valor monetario. Estos tampoco deben ser tokenizados.

Aquí es donde reconocimiento de entidad nombrada viene a jugar. Para obtener las entidades nombradas de un documento, debe usar el ents atributo. Recuperemos las entidades nombradas de la oración anterior. Ejecute el siguiente script:

for entity in sentence.ents:
    print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))

En el script anterior, imprimimos el texto de la entidad, la etiqueta de la entidad y el detalle de la entidad. La salida se ve así:

Salida:

Manchester United - ORG - Companies, agencies, institutions, etc.
Harry Kane - PERSON - People, including fictional
$90 million - MONEY - Monetary values, including unit

Puede ver que el reconocedor de entidades con nombre de spaCy ha reconocido con éxito al “Manchester United” como organización, a “Harry Kane” como persona y “$ 90 millones” como valor monetario.

Detectar sustantivos

Además de detectar entidades con nombre, también se pueden detectar sustantivos. Para hacerlo, el noun_chunks se utiliza el atributo. Considere la siguiente oración:

sentence5 = sp(u'Latest Rumours: Manchester United is looking to sign Harry Kane for $90 million')  

Intentemos encontrar los sustantivos de esta oración:

for noun in sentence5.noun_chunks:
    print(noun.text)

Salida:

Latest Rumours
Manchester United
Harry Kane

En la salida, puede ver que un sustantivo también puede ser una entidad con nombre y viceversa.

Derivado

La raíz se refiere a reducir una palabra a su forma raíz. Mientras realiza tareas de procesamiento del lenguaje natural, encontrará varios escenarios en los que encontrará diferentes palabras con la misma raíz. Por ejemplo, computación, computación, computación, computación, etc. Es posible que desee reducir las palabras a su forma raíz en aras de la uniformidad. Aquí es donde entra en juego la derivación.

Puede resultarle sorprendente, pero spaCy no contiene ninguna función para derivar, ya que se basa únicamente en la lematización. Por lo tanto, en esta sección usaremos NLTK para derivar.

Hay dos tipos de lematizadores en NLTK: Porter Stemmer y Levantadores de bolas de nieve. Ambos se han implementado utilizando diferentes algoritmos.

Porter Stemmer

Veamos a Porter Stemmer en acción:

import nltk

from nltk.stem.porter import *

Creemos una clase de PorterStemmer.

stemmer = PorterStemmer()

Supongamos que tenemos la siguiente lista y queremos reducir estas palabras a la raíz:

tokens = ['compute', 'computer', 'computed', 'computing']

La siguiente secuencia de comandos busca la raíz de las palabras de la lista utilizando porter stemmer:

for token in tokens:
    print(token + ' --> ' + stemmer.stem(token))

El resultado es el siguiente:

compute --> comput
computer --> comput
computed --> comput
computing --> comput

Puede ver que las 4 palabras se han reducido a “comput”, que en realidad no es una palabra en absoluto.

Vástago de bola de nieve

La despalilladora de bola de nieve es una versión ligeramente mejorada de la podadora Porter y generalmente se prefiere sobre esta última. Veamos el tallador de bolas de nieve en acción:

from nltk.stem.snowball import SnowballStemmer

stemmer = SnowballStemmer(language="english")

tokens = ['compute', 'computer', 'computed', 'computing']

for token in tokens:
    print(token + ' --> ' + stemmer.stem(token))

En el guión anterior, usamos Snowball Stemmer para encontrar la raíz de las mismas 4 palabras que usamos con Porter Stemmer. La salida se ve así:

compute --> comput
computer --> comput
computed --> comput
computing --> comput

Puedes ver que los resultados son los mismos. Todavía tenemos “comput” como raíz. Nuevamente, esta palabra “comput” en realidad no es una palabra de diccionario.

Aquí es donde la lematización resulta útil. La lematización reduce la palabra a su raíz tal como aparece en el diccionario. Las raíces devueltas a través de la lematización son palabras reales del diccionario y están semánticamente completas a diferencia de las palabras devueltas por la raíz.

Lematización

Aunque no pudimos realizar la derivación con spaCy, podemos realizar la lematización usando spaCy.

Para hacerlo, necesitamos usar el lemma_ atributo en el documento spaCy. Supongamos que tenemos la siguiente oración:

sentence6 = sp(u'compute computer computed computing')

Podemos encontrar las raíces de todas las palabras usando la lematización espacial de la siguiente manera:

for word in sentence6:
    print(word.text,  word.lemma_)

La salida del script anterior se ve así:

compute compute
computer computer
computed compute
computing computing

Puede ver que, a diferencia de las raíces donde la raíz que obtuvimos fue “comput”, las raíces que obtuvimos aquí son palabras reales en el diccionario.

La lematización convierte las palabras en la segunda o tercera forma a sus primeras variantes de forma. Mira el siguiente ejemplo:

sentence7 = sp(u'A letter has been written, asking him to be released')

for word in sentence7:
    print(word.text + '  ===>', word.lemma_)

Salida:

A ===> a
letter ===> letter
has ===> have
been ===> be
written ===> write
, ===> ,
asking ===> ask
him ===> -PRON-
to ===> to
be ===> be
released ===> release

Puede ver claramente en el resultado que las palabras en la segunda y tercera forma, como “escrito”, “liberado”, etc., se han convertido a la primera forma, es decir, “escribir” y “liberar”.

Conclusión

La tokenización, la derivación y la lematización son algunas de las tareas de procesamiento del lenguaje natural más fundamentales. En este artículo, vimos cómo podemos realizar Tokenización y Lematización usando la biblioteca spaCy. También vimos cómo se puede usar NLTK para derivar. En el próximo artículo, comenzaremos nuestra discusión sobre Vocabulario y Concordancia de frases en Python.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad