Breaking

Post Top Ad

Your Ad Spot

miércoles, 10 de julio de 2019

Python para NLP: creando un modelo de bolsa de palabras desde cero

Este es el artículo número 13 de mi serie de artículos sobre Python para PNL. En el artículo anterior , vimos cómo crear un simple chatbot basado en reglas que utiliza la similitud de coseno entre los vectores TF-IDF de las palabras en el corpus y la entrada del usuario, para generar una respuesta. El modelo TF-IDF se usó básicamente para convertir palabras en números.
En este artículo, estudiaremos otro modelo muy útil que convierte el texto en números, es decir, la Bolsa de Palabras (BOW).
Dado que la mayoría de los algoritmos estadísticos, por ejemplo, el aprendizaje automático y las técnicas de aprendizaje profundo, funcionan con datos numéricos, por lo tanto, tenemos que convertir el texto en números. Existen varios enfoques en este sentido. Sin embargo, los más famosos son Bag of Words, TF-IDF y word2vec. Aunque existen varias bibliotecas, como Scikit-Learn y NLTK, que pueden implementar estas técnicas en una línea de código, es importante comprender el principio de funcionamiento detrás de estas técnicas de inserción de palabras. La mejor manera de hacerlo es implementar estas técnicas desde cero en Python y esto es lo que vamos a hacer hoy.
En este artículo, veremos cómo implementar el enfoque de la Bolsa de Palabras desde cero en Python. En el siguiente artículo, veremos cómo implementar el enfoque TF-IDF desde cero en Python.
Antes de codificar, veamos primero la teoría detrás de la bolsa de palabras.

Teoría Detrás de la Bolsa de Palabras Enfoque

Para entender el enfoque de la bolsa de palabras, comencemos primero con la ayuda de un ejemplo.
Supongamos que tenemos un corpus con tres oraciones:
  • "Me gusta jugar al fútbol"
  • "¿Saliste a jugar al tenis?"
  • "John y yo jugamos al tenis"
Ahora, si tenemos que realizar una clasificación de texto, o cualquier otra tarea, en los datos anteriores utilizando técnicas estadísticas, no podemos hacerlo ya que las técnicas estadísticas solo funcionan con números. Por lo tanto necesitamos convertir estas oraciones en números.

Paso 1: Tokenize las oraciones

El primer paso en este sentido es convertir las oraciones de nuestro cuerpo en tokens o palabras individuales. Mira la tabla de abajo:
Frase 1Frase 2Frase 3
yoHizoJuan
me gustay
airyo
jugarfuera dejugar
fútbolatenis
jugar
tenis

Paso 2: Crear un diccionario de frecuencia de palabra

El siguiente paso es crear un diccionario que contenga todas las palabras de nuestro corpus como claves y la frecuencia de aparición de las palabras como valores. En otras palabras, debemos crear un histograma de las palabras en nuestro cuerpo. Mira la siguiente tabla:
PalabraFrecuencia
yo2
me gusta1
a2
jugar3
fútbol1
Hizo1
1
ir1
fuera de1
tenis2
Juan1
y1
En la tabla anterior, puede ver cada palabra en nuestro corpus junto con su frecuencia de aparición. Por ejemplo, puede ver que, dado que la palabra playaparece tres veces en el corpus (una vez en cada oración), su frecuencia es 3.
En nuestro corpus, solo tuvimos tres oraciones, por lo que es fácil para nosotros crear un diccionario que contenga todas las palabras. En los escenarios del mundo real, habrá millones de palabras en el diccionario. Algunas de las palabras tendrán una frecuencia muy pequeña. Las palabras con una frecuencia muy pequeña no son muy útiles, por lo tanto, esas palabras se eliminan. Una forma de eliminar las palabras con menos frecuencia es ordenar la palabra diccionario de frecuencia en el orden decreciente de la frecuencia y luego filtrar las palabras que tienen una frecuencia mayor que un cierto umbral.
Vamos a ordenar nuestro diccionario de frecuencia de palabras:
PalabraFrecuencia
jugar3
tenis2
a2
yo2
fútbol1
Hizo1
1
ir1
fuera de1
me gusta1
Juan1
y1

Paso 3: Creando el Modelo de Bolsa de Palabras

Para crear el modelo de bolsa de palabras, necesitamos crear una matriz donde las columnas correspondan a las palabras más frecuentes en nuestro diccionario donde las filas correspondan al documento o las oraciones.
Supongamos que filtramos las 8 palabras más frecuentes de nuestro diccionario. Entonces la matriz de frecuencia de documentos se verá así:
JugarTenisAyoFútbolHizoir
Frase 110111000
Frase 211100111
Frase 311010000
Es importante entender cómo se crea la matriz anterior. En la matriz anterior, la primera fila corresponde a la primera oración. En la primera, la palabra "juego" aparece una vez, por lo tanto, agregamos 1 en la primera columna. La palabra en la segunda columna es "Tenis", no aparece en la primera oración, por lo tanto, agregamos un 0 en la segunda columna para la oración 1. De manera similar, en la segunda oración, las palabras "Jugar" y "Tenis "ocurre una vez, por lo tanto agregamos 1 en las dos primeras columnas. Sin embargo, en la quinta columna, agregamos un 0, ya que la palabra "Fútbol" no aparece en la segunda oración. De esta manera, todas las celdas de la matriz anterior se rellenan con 0 o 1, dependiendo de la aparición de la palabra. Matriz final corresponde al modelo de bolsa de palabras.
En cada fila, puede ver la representación numérica de la oración correspondiente. Por ejemplo, la primera fila muestra la representación numérica de la oración 1 . Esta representación numérica ahora se puede utilizar como entrada para los modelos estadísticos.
Basta de la teoría, implementemos nuestro propio modelo de bolsa de palabras desde cero.

Bolsa de palabras modelo en Python

Lo primero que necesitamos para crear nuestro modelo de Bolsa de palabras es un conjunto de datos. En la sección anterior, creamos manualmente un modelo de bolsa de palabras con tres oraciones. Sin embargo, los conjuntos de datos del mundo real son enormes con millones de palabras. La mejor manera de encontrar un corpus al azar es Wikipedia.
En el primer paso, rasparemos el artículo de Wikipedia sobre el procesamiento del lenguaje natural . Pero primero, importemos las bibliotecas requeridas:
import nltk  
import numpy as np  
import random  
import string

import bs4 as bs  
import urllib.request  
import re  
Como hicimos en el artículo anterior, usaremos la biblioteca Beautifulsoup4 para analizar los datos de Wikipedia. Por otra parte, la biblioteca de expresiones regulares de Python , rese utilizará para algunas tareas de procesamiento previo en el texto.
A continuación, debemos raspar el artículo de Wikipedia sobre el procesamiento del lenguaje natural.
raw_html = urllib.request.urlopen('https://en.wikipedia.org/wiki/Natural_language_processing')  
raw_html = raw_html.read()

article_html = bs.BeautifulSoup(raw_html, 'lxml')

article_paragraphs = article_html.find_all('p')

article_text = ''

for para in article_paragraphs:  
    article_text += para.text
En el script anterior, importamos el HTML sin procesar para el artículo de Wikipedia. Desde el HTML sin procesar, filtramos el texto dentro del texto del párrafo. Finalmente, creamos un corpus completo al concatenar todos los párrafos.
El siguiente paso es dividir el corpus en oraciones individuales. Para hacerlo, usaremos la sent_tokenizefunción de la biblioteca NLTK.
corpus = nltk.sent_tokenize(article_text)  
Nuestro texto contiene puntuaciones. No queremos que las puntuaciones sean parte de nuestro diccionario de frecuencia de palabras. En la siguiente secuencia de comandos, primero convertimos nuestro texto en minúsculas y luego eliminamos la puntuación de nuestro texto. Eliminar la puntuación puede resultar en múltiples espacios vacíos. Eliminaremos los espacios vacíos del texto usando regex.
Mira el siguiente script:
for i in range(len(corpus )):  
    corpus [i] = corpus [i].lower()
    corpus [i] = re.sub(r'\W',' ',corpus [i])
    corpus [i] = re.sub(r'\s+',' ',corpus [i])
En el guión anterior, iteramos a través de cada oración en el corpus, convertimos la oración a minúsculas, y luego eliminamos la puntuación y los espacios vacíos del texto.
Averigüemos el número de oraciones en nuestro corpus.
print(len(corpus))  
La salida muestra 49.
Imprimamos una frase de nuestro corpus:
print(corpus[30])  
Salida:
in the 2010s representation learning and deep neural network style machine learning methods became widespread in natural language processing due in part to a flurry of results showing that such techniques 4 5 can achieve state of the art results in many natural language tasks for example in language modeling 6 parsing 7 8 and many others  
Puede ver que el texto no contiene ningún carácter especial o varios espacios vacíos.
Ahora tenemos nuestro propio corpus. El siguiente paso es tokenizar las oraciones en el corpus y crear un diccionario que contenga palabras y sus correspondientes frecuencias en el corpus. Mira el siguiente script:
wordfreq = {}  
for sentence in corpus:  
    tokens = nltk.word_tokenize(sentence)
    for token in tokens:
        if token not in wordfreq.keys():
            wordfreq[token] = 1
        else:
            wordfreq[token] += 1
En el script anterior creamos un diccionario llamado wordfreqA continuación, iteramos a través de cada oración en el corpus. La oración es tokenizada en palabras. A continuación, iteramos a través de cada palabra en la oración. Si la palabra no existe en el wordfreqdiccionario, la agregaremos como la clave y estableceremos el valor de la palabra en 1. De lo contrario, si la palabra ya existe en el diccionario, simplemente incrementaremos el recuento de la clave en 1 .
Si está ejecutando lo anterior en el editor de Spyder como yo, puede ir al explorador de variables a la derecha y hacer clic en la wordfreqvariable. Deberías ver un diccionario como este:
Puede ver las palabras en la columna "Clave" y su frecuencia de ocurrencias en la columna "Valor".
Como dije en la sección de teoría, dependiendo de la tarea en cuestión, no todas las palabras son útiles. En grandes cuerpos, puedes tener millones de palabras. Podemos filtrar las palabras más frecuentes. Nuestro corpus tiene 535 palabras en total. Filtrémonos hasta las 200 palabras más frecuentes. Para ello, podemos hacer uso de la heapbiblioteca de Python .
Mira el siguiente script:
import heapq  
most_freq = heapq.nlargest(200, wordfreq, key=wordfreq.get)  
Ahora nuestra most_freqlista contiene las 200 palabras que aparecen con mayor frecuencia junto con su frecuencia de aparición.
El paso final es convertir las oraciones en nuestro corpus en su correspondiente representación vectorial. La idea es sencilla, para cada palabra en el most_freqdiccionario, si la palabra existe en la oración, se agregará un 1 para la palabra, de lo contrario se agregará 0.
sentence_vectors = []  
for sentence in corpus:  
    sentence_tokens = nltk.word_tokenize(sentence)
    sent_vec = []
    for token in most_freq:
        if token in sentence_tokens:
            sent_vec.append(1)
        else:
            sent_vec.append(0)
    sentence_vectors.append(sent_vec)
En el guión anterior creamos una lista vacía sentence_vectorsque almacenará vectores para todas las oraciones en el corpus. A continuación, iteramos a través de cada oración en el corpus y creamos una lista vacía sent_vecpara las oraciones individuales. Del mismo modo, también tokenize la oración. A continuación, iteramos a través de cada palabra en la most_freqlista y verificamos si la palabra existe en los tokens para la oración. Si la palabra es parte de la oración, 1 se agrega al vector de oración individual sent_vec, de lo contrario se agrega 0. Finalmente, el vector de oración se agrega a la lista sentence_vectorsque contiene vectores para todas las oraciones. Básicamente, este sentence_vectorses nuestro modelo de bolsa de palabras.
Sin embargo, el modelo de bolsa de palabras que vimos en la sección de teoría tenía la forma de una matriz. Nuestro modelo está en la forma de una lista de listas. Podemos convertir nuestro modelo en forma de matriz usando este script:
sentence_vectors = np.asarray(sentence_vectors)  
Básicamente, en el siguiente script, convertimos nuestra lista en una matriz numpy bidimensional usando la asarrayfunción. Ahora, si abre la sentence_vectorsvariable en el explorador de variables del editor de Spyder, debería ver la siguiente matriz:
Puedes ver el modelo de la Bolsa de Palabras que contiene 0 y 1.

Conclusión

El modelo Bag of Words es uno de los tres métodos de inserción de palabras más utilizados con TF-IDF y Word2Vec, siendo los otros dos.
En este artículo, vimos cómo implementar el enfoque de la Bolsa de Palabras desde cero en Python. La teoría del enfoque se ha explicado junto con el código práctico para implementar el enfoque. En el siguiente artículo , veremos cómo implementar el enfoque TF-IDF desde cero en Python.

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas