Python para PNL: trabajar con la biblioteca de texto rápido de Facebook

Este es el vigésimo artículo de mi serie de artículos sobre Python para PNL. En los últimos artículos, hemos estado explorando técnicas de aprendizaje profundo para realizar una va...

Este es el vigésimo artículo de mi serie de artículos sobre Python para PNL. En los últimos artículos, hemos estado explorando técnicas de aprendizaje profundo para realizar una variedad de tareas de aprendizaje automático, y también debe estar familiarizado con el concepto de incrustaciones de palabras. Las incrustaciones de palabras son una forma de convertir información textual en forma numérica, que a su vez se puede usar como entrada para algoritmos estadísticos. En mi artículo sobre incrustaciones de palabras, expliqué cómo podemos crear nuestras propias incrustaciones de palabras y cómo podemos usar incrustaciones de palabras integradas como Guante.

En este artículo, vamos a estudiar Texto rápido, que es otro módulo extremadamente útil para la incrustación de palabras y la clasificación de textos. FastText ha sido desarrollado por Facebook y ha mostrado excelentes resultados en muchos problemas de NLP, como la detección de similitudes semánticas y la clasificación de textos.

En este artículo, exploraremos brevemente la biblioteca FastText. Este artículo se divide en dos secciones. En la primera sección, veremos cómo la biblioteca FastText crea representaciones vectoriales que se pueden usar para encontrar similitudes semánticas entre las palabras. En la segunda sección, veremos la aplicación de la biblioteca FastText para la clasificación de textos.

FastText para similitud semántica

FastText admite ambos [modelos de bolsa continua de palabras y Skip-Gram] (https://en.wikipedia.org/wiki/Word2vec#CBOW_and_skip_grams). En este artículo, implementaremos el modelo skip-gram para aprender la representación vectorial de palabras. //en.wikipedia.org/wiki/Machine_learning), aprendizaje profundo y Redes neuronales. Dado que estos temas son bastante similares, los elegimos para tener una cantidad sustancial de datos para crear un corpus. Puede agregar más temas de naturaleza similar si lo desea.

Como primer paso, necesitamos importar las bibliotecas requeridas. Haremos uso de la Biblioteca de Wikipedia para Python, la cual se puede descargar mediante el siguiente comando:

1
$ pip install wikipedia

Importación de bibliotecas

El siguiente script importa las bibliotecas requeridas en nuestra aplicación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from keras.preprocessing.text import Tokenizer
from gensim.models.fasttext import FastText
import numpy as np
import matplotlib.pyplot as plt
import nltk
from string import punctuation
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import sent_tokenize
from nltk import WordPunctTokenizer

import wikipedia
import nltk
nltk.download('punkt')
nltk.download('wordnet')
nltk.download('stopwords')
en_stop = set(nltk.corpus.stopwords.words('english'))

%matplotlib inline

Puede ver que estamos usando el módulo FastText de la biblioteca gensim.models.fasttext. Para la representación de palabras y la similitud semántica, podemos usar el modelo Gensim para FastText. Este modelo puede ejecutarse en Windows, sin embargo, para la clasificación de texto, tendremos que usar la plataforma Linux. Eso lo veremos en la siguiente sección.

Scraping de artículos de Wikipedia

En este paso, rasparemos los artículos requeridos de Wikipedia. Mira el siguiente guión:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
artificial_intelligence = wikipedia.page("Artificial Intelligence").content
machine_learning = wikipedia.page("Machine Learning").content
deep_learning = wikipedia.page("Deep Learning").content
neural_network = wikipedia.page("Neural Network").content

artificial_intelligence = sent_tokenize(artificial_intelligence)
machine_learning = sent_tokenize(machine_learning)
deep_learning = sent_tokenize(deep_learning)
neural_network = sent_tokenize(neural_network)

artificial_intelligence.extend(machine_learning)
artificial_intelligence.extend(deep_learning)
artificial_intelligence.extend(neural_network)

Para extraer una página de Wikipedia, podemos usar el método page del módulo wikipedia. El nombre de la página que desea descartar se pasa como parámetro al método página. El método devuelve el objeto WikipediaPage, que luego puede usar para recuperar el contenido de la página a través del atributo content, como se muestra en el script anterior.

Luego, el contenido extraído de las cuatro páginas de Wikipedia se tokeniza en oraciones utilizando el método sent_tokenize. El método sent_tokenize devuelve una lista de oraciones. Las oraciones de las cuatro páginas se tokenizan por separado. Finalmente, las oraciones de los cuatro artículos se unen mediante el método extender.

Preprocesamiento de datos {#preprocesamiento de datos}

El siguiente paso es limpiar nuestros datos de texto eliminando puntuaciones y números. También convertiremos los datos a minúsculas. Las palabras en nuestros datos serán lematizadas a su forma raíz. Además, las palabras vacías y las palabras de longitud inferior a 4 serán eliminadas del corpus.

La función preprocess_text, como se define a continuación, realiza las tareas de preprocesamiento.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import re
from nltk.stem import WordNetLemmatizer

stemmer = WordNetLemmatizer()

def preprocess_text(document):
        # Remove all the special characters
        document = re.sub(r'\W', ' ', str(document))

        # remove all single characters
        document = re.sub(r'\s+[a-zA-Z]\s+', ' ', document)

        # Remove single characters from the start
        document = re.sub(r'\^[a-zA-Z]\s+', ' ', document)

        # Substituting multiple spaces with single space
        document = re.sub(r'\s+', ' ', document, flags=re.I)

        # Removing prefixed 'b'
        document = re.sub(r'^b\s+', '', document)

        # Converting to Lowercase
        document = document.lower()

        # Lemmatization
        tokens = document.split()
        tokens = [stemmer.lemmatize(word) for word in tokens]
        tokens = [word for word in tokens if word not in en_stop]
        tokens = [word for word in tokens if len(word) > 3]

        preprocessed_text = ' '.join(tokens)

        return preprocessed_text

Veamos si nuestra función realiza la tarea deseada preprocesando una oración ficticia:

1
2
3
4
5
6
7
8
sent = preprocess_text("Artificial intelligence, is the most advanced technology of the present era")
print(sent)


final_corpus = [preprocess_text(sentence) for sentence in artificial_intelligence if sentence.strip() !='']

word_punctuation_tokenizer = nltk.WordPunctTokenizer()
word_tokenized_corpus = [word_punctuation_tokenizer.tokenize(sent) for sent in final_corpus]

La oración preprocesada se ve así:

1
artificial intelligence advanced technology present

Puede ver que se han eliminado los signos de puntuación y las palabras vacías, y se han lematizado las oraciones. Además, también se han eliminado palabras con una longitud inferior a 4, como "era". Estas opciones se eligieron al azar para esta prueba, por lo que puede permitir las palabras con longitudes más pequeñas o más largas en el corpus.

Creación de representación de palabras

Hemos preprocesado nuestro corpus. Ahora es el momento de crear representaciones de palabras usando FastText. Primero definamos los hiperparámetros para nuestro modelo FastText:

1
2
3
4
embedding_size = 60
window_size = 40
min_word = 5
down_sampling = 1e-2

Aquí embedding_size es el tamaño del vector de incrustación. En otras palabras, cada palabra de nuestro corpus se representará como un vector de 60 dimensiones. El tamaño_ventana es el tamaño de la cantidad de palabras que ocurren antes y después de la palabra en función de las cuales se aprenderán las representaciones de la palabra. Esto puede sonar complicado, sin embargo, en el modelo skip-gram ingresamos una palabra en el algoritmo y la salida son las palabras de contexto. Si el tamaño de la ventana es 40, para cada entrada habrá 80 salidas: 40 palabras que ocurren antes de la palabra de entrada y 40 palabras que ocurren después de la palabra de entrada. Las incrustaciones de palabras para la palabra de entrada se aprenden utilizando estas 80 palabras de salida.

El siguiente hiperparámetro es min_word, que especifica la frecuencia mínima de una palabra en el corpus para el cual se generarán las representaciones de palabras. Finalmente, la palabra que aparece con más frecuencia será muestreada por un número especificado por el atributo down_sampling.

Ahora vamos a crear nuestro modelo FastText para representaciones de palabras.

1
2
3
4
5
6
7
8
%%time
ft_model = FastText(word_tokenized_corpus,
                      size=embedding_size,
                      window=window_size,
                      min_count=min_word,
                      sample=down_sampling,
                      sg=1,
                      iter=100)

Todos los parámetros en el script anterior se explican por sí mismos, excepto sg. El parámetro sg define el tipo de modelo que queremos crear. Un valor de 1 especifica que queremos crear un modelo skip-gram. Mientras que cero especifica el modelo de bolsa de palabras, que también es el valor predeterminado.

Ejecute el script anterior. Puede tardar un tiempo en ejecutarse. En mi máquina, las estadísticas de tiempo para que se ejecute el código anterior son las siguientes:

1
2
CPU times: user 1min 45s, sys: 434 ms, total: 1min 45s
Wall time: 57.2 s

Veamos ahora la representación de la palabra "artificial". Para hacerlo, puedes usar el método wv del objeto FastText y pasarle el nombre de la palabra dentro de una lista.

1
print(ft_model.wv['artificial'])

Aquí está la salida:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[-3.7653010e-02 -4.5558015e-01  3.2035065e-01 -1.5289043e-01
  4.0645871e-02 -1.8946664e-01  7.0426887e-01  2.8806925e-01
 -1.8166199e-01  1.7566417e-01  1.1522485e-01 -3.6525184e-01
 -6.4378887e-01 -1.6650060e-01  7.4625671e-01 -4.8166099e-01
  2.0884991e-01  1.8067230e-01 -6.2647951e-01  2.7614883e-01
 -3.6478557e-02  1.4782918e-02 -3.3124462e-01  1.9372456e-01
  4.3028224e-02 -8.2326338e-02  1.0356739e-01  4.0792203e-01
 -2.0596240e-02 -3.5974573e-02  9.9928051e-02  1.7191900e-01
 -2.1196717e-01  6.4424530e-02 -4.4705093e-02  9.7391091e-02
 -2.8846195e-01  8.8607501e-03  1.6520244e-01 -3.6626378e-01
 -6.2017748e-04 -1.5083785e-01 -1.7499258e-01  7.1994811e-02
 -1.9868813e-01 -3.1733567e-01  1.9832127e-01  1.2799081e-01
 -7.6522082e-01  5.2335665e-02 -4.5766738e-01 -2.7947658e-01
  3.7890410e-03 -3.8761377e-01 -9.3001537e-02 -1.7128626e-01
 -1.2923178e-01  3.9627206e-01 -3.6673656e-01  2.2755004e-01]

En el resultado anterior, puede ver un vector de 60 dimensiones para la palabra "artificial"

Busquemos ahora las 5 palabras más similares para las palabras 'artificial', 'intelligence', 'machine', 'network', 'recurrent', 'deep'. Puede elegir cualquier número de palabras. El siguiente script imprime las palabras especificadas junto con las 5 palabras más similares.

1
2
3
4
5
semantically_similar_words = {words: [item[0] for item in ft_model.wv.most_similar([words], topn=5)]
                  for words in ['artificial', 'intelligence', 'machine', 'network', 'recurrent', 'deep']}

for k,v in semantically_similar_words.items():
    print(k+":"+str(v))

La salida es la siguiente:

1
2
3
4
5
6
artificial:['intelligence', 'inspired', 'book', 'academic', 'biological']
intelligence:['artificial', 'human', 'people', 'intelligent', 'general']
machine:['ethic', 'learning', 'concerned', 'argument', 'intelligence']
network:['neural', 'forward', 'deep', 'backpropagation', 'hidden']
recurrent:['rnns', 'short', 'schmidhuber', 'shown', 'feedforward']
deep:['convolutional', 'speech', 'network', 'generative', 'neural']

También podemos encontrar la similitud del coseno entre los vectores para dos palabras cualesquiera, como se muestra a continuación:

1
print(ft_model.wv.similarity(w1='artificial', w2='intelligence'))

La salida muestra un valor de "0.7481". El valor puede estar entre 0 y 1. Un valor más alto significa una mayor similitud.

Visualización de similitudes de palabras {#visualización de similitudes de palabras}

Aunque cada palabra en nuestro modelo se representa como un vector de 60 dimensiones, podemos usar la técnica de análisis de componentes principales para encontrar dos componentes principales. Los dos componentes principales se pueden usar para trazar las palabras en un espacio bidimensional. Sin embargo, primero necesitamos crear una lista de todas las palabras en el diccionario semantically_similar_words. El siguiente script hace eso:

1
2
3
4
5
6
7
from sklearn.decomposition import PCA

all_similar_words = sum([[k] + v for k, v in semantically_similar_words.items()], [])

print(all_similar_words)
print(type(all_similar_words))
print(len(all_similar_words))

En el script anterior, iteramos a través de todos los pares clave-valor en el diccionario semantically_similar_words. Cada clave en el diccionario es una palabra. El valor correspondiente es una lista de todas las palabras semánticamente similares. Dado que encontramos las 5 palabras más similares para una lista de 6 palabras, es decir, 'artificial', 'intelligence', 'machine', 'network', 'recurrent', 'deep\ ‘, verá que habrá 30 elementos en la lista all_similar_words.

Luego, tenemos que encontrar los vectores de palabras para todas estas 30 palabras y luego usar PCA para reducir las dimensiones de los vectores de palabras de 60 a 2. Luego podemos usar el método plt, que es un alias de matplotlib Método .pyplot para trazar las palabras en un espacio vectorial bidimensional.

Ejecute el siguiente script para visualizar las palabras:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
word_vectors = ft_model.wv[all_similar_words]

pca = PCA(n_components=2)

p_comps = pca.fit_transform(word_vectors)
word_names = all_similar_words

plt.figure(figsize=(18, 10))
plt.scatter(p_comps[:, 0], p_comps[:, 1], c='red')

for word_names, x, y in zip(word_names, p_comps[:, 0], p_comps[:, 1]):
    plt.annotate(word_names, xy=(x+0.06, y+0.03), xytext=(0, 0), textcoords='offset points')

La salida del script anterior se ve así:

Puede ver que las palabras que aparecen juntas con frecuencia en el texto también están cerca unas de otras en el plano bidimensional. Por ejemplo, las palabras "profundo" y "red" casi se superponen. Del mismo modo, las palabras "feedforward" y "backpropagation" también están muy cerca.

Ahora sabemos cómo crear incrustaciones de palabras usando FastText. En la siguiente sección, veremos cómo se puede usar FastText para tareas de clasificación de texto.

FastText para clasificación de texto

La clasificación de texto se refiere a la clasificación de datos textuales en categorías predefinidas en función del contenido del texto. El análisis de sentimientos, la detección de spam y la detección de etiquetas son algunos de los ejemplos más comunes de casos de uso para la clasificación de texto.

El módulo de clasificación de texto FastText solo se puede ejecutar a través de Linux u OSX. Si es usuario de Windows, puede usar Colaborador de Google para ejecutar el módulo de clasificación de texto FastText. Todos los scripts de esta sección se han ejecutado con Google Colaboratory.

El conjunto de datos

El conjunto de datos para este artículo se puede descargar desde este Enlace Kaggle. El conjunto de datos contiene varios archivos, pero solo nos interesa el archivo yelp_review.csv. El archivo contiene más de 5,2 millones de reseñas sobre diferentes negocios, incluidos restaurantes, bares, dentistas, médicos, salones de belleza, etc. Sin embargo, solo usaremos los primeros 50 000 registros para entrenar nuestro modelo debido a limitaciones de memoria. Puedes probar con más registros si quieres.

Importemos las bibliotecas requeridas y carguemos el conjunto de datos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd
import numpy as np

yelp_reviews = pd.read_csv("/content/drive/My Drive/Colab Datasets/yelp_review_short.csv")

bins = [0,2,5]
review_names = ['negative', 'positive']

yelp_reviews['reviews_score'] = pd.cut(yelp_reviews['stars'], bins, labels=review_names)

yelp_reviews.head()

En el script de arriba cargamos el archivo yelp_review_short.csv que contiene 50,000 reseñas con la función pd.read_csv.

Simplificaremos nuestro problema convirtiendo los valores numéricos de las revisiones en valores categóricos. Esto se hará agregando una nueva columna, reviews_score, a nuestro conjunto de datos. Si la reseña del usuario tiene un valor entre 1 y 2 en la columna “Estrellas” (que califica a la empresa en una escala de 1 a 5), ​​la columna “reviews_score” tendrá un valor de cadena “negativo”. Si la calificación está entre 3 y 5 en la columna Estrellas, la columna reviews_score contendrá un valor positivo. Esto hace que nuestro problema sea un problema de clasificación binaria.

Finalmente, el encabezado del marco de datos se imprime como se muestra a continuación:

Instalación de FastText {#instalación de FastText}

El siguiente paso es importar modelos de FastText, que se pueden importar usando el comando wget desde el repositorio de GitHub, como se muestra en el siguiente script:

1
!wget https://github.com/facebookresearch/fastText/archive/v0.1.0.zip

Nota: si está ejecutando el comando anterior desde una terminal de Linux, no es necesario que anteponga el prefijo ! antes del comando anterior. En el cuaderno de Google Colaboratory, cualquier comando después de ! se ejecuta como un comando de shell y no dentro del intérprete de Python. Por lo tanto, todos los comandos que no son de Python aquí tienen el prefijo !.

Si ejecuta el script anterior y ve los siguientes resultados, eso significa que FastText se ha descargado correctamente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
--2019-08-16 15:05:05--  https://github.com/facebookresearch/fastText/archive/v0.1.0.zip
Resolving github.com (github.com)... 140.82.113.4
Connecting to github.com (github.com)|140.82.113.4|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/facebookresearch/fastText/zip/v0.1.0 [following]
--2019-08-16 15:05:05--  https://codeload.github.com/facebookresearch/fastText/zip/v0.1.0
Resolving codeload.github.com (codeload.github.com)... 192.30.255.121
Connecting to codeload.github.com (codeload.github.com)|192.30.255.121|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: v0.1.0.zip

v0.1.0.zip              [ <=>                ]  92.06K  --.-KB/s    in 0.03s

2019-08-16 15:05:05 (3.26 MB/s) - v0.1.0.zip saved [94267]

El siguiente paso es descomprimir los módulos de FastText. Simplemente escriba el siguiente comando:

1
!unzip v0.1.0.zip

A continuación, debe navegar hasta el directorio donde descargó FastText y luego ejecutar el comando !make para ejecutar los binarios de C++. Ejecute los siguientes pasos:

1
2
cd fastText-0.1.0
!make

Si ve el siguiente resultado, eso significa que FastText se instaló correctamente en su máquina.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/args.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/dictionary.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/productquantizer.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/matrix.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/qmatrix.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/vector.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/model.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/utils.cc
c++ -pthread -std=c++0x -O3 -funroll-loops -c src/fasttext.cc
c++ -pthread -std=c++0x -O3 -funroll-loops args.o dictionary.o productquantizer.o matrix.o qmatrix.o vector.o model.o utils.o fasttext.o src/main.cc -o fasttext

Para verificar la instalación, ejecute el siguiente comando:

1
!./fasttext

Debería ver que estos comandos son compatibles con FastText:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
usage: fasttext <command> <args>

The commands supported by FastText are:

  supervised              train a supervised classifier
  quantize                quantize a model to reduce the memory usage
  test                    evaluate a supervised classifier
  predict                 predict most likely labels
  predict-prob            predict most likely labels with probabilities
  skipgram                train a skipgram model
  cbow                    train a cbow model
  print-word-vectors      print word vectors given a trained model
  print-sentence-vectors  print sentence vectors given a trained model
  nn                      query for nearest neighbors
  analogies               query for analogies

Clasificación de texto {#clasificación de texto}

Antes de entrenar modelos de FastText para realizar la clasificación de texto, es pertinente mencionar que FastText acepta datos en un formato especial, que es el siguiente:

1
2
_label_tag This is sentence 1
_label_tag2 This is sentence 2.

Si miramos nuestro conjunto de datos, no está en el formato deseado. El texto con sentimiento positivo debería verse así:

1
__label__positive burgers are very big portions here.

Del mismo modo, las críticas negativas deberían verse así:

1
__label__negative They do not use organic ingredients, but I thi...

La siguiente secuencia de comandos filtra las columnas reviews_score y text del conjunto de datos y luego agrega el prefijo __label__ antes de todos los valores en la columna reviews_score. Del mismo modo, \n y \t se reemplazan por un espacio en la columna texto. Finalmente, el marco de datos actualizado se escribe en el disco en forma de yelp_reviews_updated.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pandas as pd
from io import StringIO
import csv

col = ['reviews_score', 'text']

yelp_reviews = yelp_reviews[col]
yelp_reviews['reviews_score']=['__label__'+ s for s in yelp_reviews['reviews_score']]
yelp_reviews['text']= yelp_reviews['text'].replace('\n',' ', regex=True).replace('\t',' ', regex=True)
yelp_reviews.to_csv(r'/content/drive/My Drive/Colab Datasets/yelp_reviews_updated.txt', index=False, sep=' ', header=False, quoting=csv.QUOTE_NONE, quotechar="", escapechar=" ")

Ahora imprimamos el encabezado del marco de datos yelp_reviews actualizado.

1
yelp_reviews.head()

Deberías ver los siguientes resultados:

1
2
3
4
5
6
reviews_score   text
0   __label__positive   Super simple place but amazing nonetheless. It...
1   __label__positive   Small unassuming place that changes their menu...
2   __label__positive   Lester's is located in a beautiful neighborhoo...
3   __label__positive   Love coming here. Yes the place always needs t...
4   __label__positive   Had their chocolate almond croissant and it wa...

De manera similar, la cola del marco de datos se ve así:

1
2
3
4
5
6
    reviews_score   text
49995   __label__positive   This is an awesome consignment store! They hav...
49996   __label__positive   Awesome laid back atmosphere with made-to-orde...
49997   __label__positive   Today was my first appointment and I can hones...
49998   __label__positive   I love this chic salon. They use the best prod...
49999   __label__positive   This place is delicious. All their meats and s...

Hemos convertido nuestro conjunto de datos en la forma requerida. El siguiente paso es dividir nuestros datos en conjuntos de entrenamiento y prueba. El 80 % de los datos, es decir, los primeros 40 000 registros de 50 000 registros se usarán para entrenar los datos, mientras que el 20 % de los datos (los últimos 10 000 registros) se usarán para evaluar el rendimiento del algoritmo.

El siguiente script divide los datos en conjuntos de entrenamiento y prueba:

1
2
!head -n 40000 "/content/drive/My Drive/Colab Datasets/yelp_reviews_updated.txt" > "/content/drive/My Drive/Colab Datasets/yelp_reviews_train.txt"
!tail -n 10000 "/content/drive/My Drive/Colab Datasets/yelp_reviews_updated.txt" > "/content/drive/My Drive/Colab Datasets/yelp_reviews_test.txt"

Una vez que se ejecuta el script anterior, se generará el archivo yelp_reviews_train.txt, que contiene los datos de entrenamiento. Del mismo modo, el archivo yelp_reviews_test.txt recién generado contendrá datos de prueba.

Ahora es el momento de entrenar nuestro algoritmo de clasificación de texto FastText.

1
2
%%time
!./fasttext supervised -input "/content/drive/My Drive/Colab Datasets/yelp_reviews_train.txt" -output model_yelp_reviews

Para entrenar el algoritmo tenemos que usar el comando supervisado y pasarle el archivo de entrada. El nombre del modelo se especifica después de la palabra clave -output. El script anterior dará como resultado un modelo de clasificación de texto entrenado llamado model_yelp_reviews.bin. Aquí está el resultado del script anterior:

1
2
3
4
5
6
Read 4M words
Number of words:  177864
Number of labels: 2
Progress: 100.0%  words/sec/thread: 2548017  lr: 0.000000  loss: 0.246120  eta: 0h0m
CPU times: user 212 ms, sys: 48.6 ms, total: 261 ms
Wall time: 15.6 s

Puede echar un vistazo al modelo a través del comando !ls como se muestra a continuación:

1
!ls

Aquí está la salida:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
args.o             Makefile         quantization-results.sh
classification-example.sh  matrix.o         README.md
classification-results.sh  model.o          src
CONTRIBUTING.md        model_yelp_reviews.bin   tutorials
dictionary.o           model_yelp_reviews.vec   utils.o
eval.py            PATENTS          vector.o
fasttext           pretrained-vectors.md    wikifil.pl
fasttext.o         productquantizer.o       word-vector-example.sh
get-wikimedia.sh       qmatrix.o            yelp_reviews_train.txt
LICENSE            quantization-example.sh

Puede ver model_yelp_reviews.bin en la lista de documentos anterior.

Finalmente, para probar el modelo puedes usar el comando test. Debe especificar el nombre del modelo y el archivo de prueba después del comando test, como se muestra a continuación:

1
!./fasttext test model_yelp_reviews.bin "/content/drive/My Drive/Colab Datasets/yelp_reviews_test.txt"

La salida del script anterior se ve así:

1
2
3
4
N   10000
[correo electrónico protegido] 0.909
[correo electrónico protegido] 0.909
Number of examples: 10000

Here [correo electrónico protegido] refers to precision and [correo electrónico protegido]refers to recall. You can see our model achieves precision and recall of 0.909 which is pretty good.

Intentemos ahora limpiar nuestro texto de puntuaciones, caracteres especiales y convertirlo a minúsculas para mejorar la uniformidad del texto. El siguiente script limpia el juego de trenes:

1
!cat "/content/drive/My Drive/Colab Datasets/yelp_reviews_train.txt" | sed -e "s/\([.\!?,’/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > "/content/drive/My Drive/Colab Datasets/yelp_reviews_train_clean.txt"

Y el siguiente script limpia el conjunto de prueba:

1
"/content/drive/My Drive/Colab Datasets/yelp_reviews_test.txt" | sed -e "s/\([.\!?,’/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > "/content/drive/My Drive/Colab Datasets/yelp_reviews_test_clean.txt"

Ahora, entrenaremos el modelo en el conjunto de entrenamiento limpio:

1
2
%%time
!./fasttext supervised -input "/content/drive/My Drive/Colab Datasets/yelp_reviews_train_clean.txt" -output model_yelp_reviews

Y finalmente, usaremos el modelo entrenado en el conjunto de entrenamiento limpio para hacer predicciones en el conjunto de prueba limpio:

1
!./fasttext test model_yelp_reviews.bin "/content/drive/My Drive/Colab Datasets/yelp_reviews_test_clean.txt"

El resultado del script anterior es el siguiente:

1
2
3
4
N   10000
[correo electrónico protegido] 0.915
[correo electrónico protegido] 0.915
Number of examples: 10000

Puede ver un ligero aumento tanto en la precisión como en la recuperación. Para mejorar aún más el modelo, puede aumentar las épocas y la tasa de aprendizaje del modelo. El siguiente script establece el número de épocas en 30 y la tasa de aprendizaje en 0,5.

1
2
%%time
!./fasttext supervised -input "/content/drive/My Drive/Colab Datasets/yelp_reviews_train_clean.txt" -output model_yelp_reviews -epoch 30 -lr 0.5

Puede probar diferentes números y ver si puede obtener mejores resultados. ¡No olvides compartir tus resultados en los comentarios!

Yendo más lejos: proyecto de extremo a extremo portátil

¿Tu naturaleza inquisitiva te hace querer ir más allá? Recomendamos consultar nuestro Proyecto guiado: ["Subtítulos de imágenes con CNN y Transformers con Keras"](https://wikihtp.com/courses/image-captioning-with-cnns-and -transformadores-con-keras/#cta){target="_blank"}.

En este proyecto guiado, aprenderá a crear un modelo de subtítulos de imágenes, que acepta una imagen como entrada y produce un subtítulo de texto como salida.

Aprenderás a:

  • Preprocesar texto
  • Vectorizar la entrada de texto fácilmente
  • Trabaje con la API tf.data y cree conjuntos de datos de alto rendimiento
  • Cree Transformers desde cero con TensorFlow/Keras y KerasNLP: la adición horizontal oficial a Keras para crear modelos NLP de última generación
  • Cree arquitecturas híbridas donde la salida de una red se codifica para otra

¿Cómo enmarcamos los subtítulos de las imágenes? La mayoría lo considera un ejemplo de aprendizaje profundo generativo, porque estamos enseñando a una red a generar descripciones. Sin embargo, me gusta verlo como una instancia de traducción automática neuronal: estamos traduciendo las características visuales de una imagen en palabras. A través de la traducción, estamos generando una nueva representación de esa imagen, en lugar de simplemente generar un nuevo significado. Verlo como traducción, y solo por generación de extensión, enfoca la tarea bajo una luz diferente y la hace un poco más intuitiva.

Enmarcar el problema como uno de traducción hace que sea más fácil averiguar qué arquitectura querremos usar. Los transformadores solo de codificador son excelentes para comprender el texto (análisis de opinión, clasificación, etc.) porque los codificadores codifican representaciones significativas. Los modelos de solo decodificador son excelentes para la generación (como GPT-3), ya que los decodificadores pueden inferir representaciones significativas en otra secuencia con el mismo significado. La traducción generalmente se realiza mediante una arquitectura de codificador-decodificador, donde los codificadores codifican una representación significativa de una oración (o imagen, en nuestro caso) y los decodificadores aprenden a convertir esta secuencia en otra representación significativa que es más interpretable para nosotros (como una oración).

Conclusión

El modelo FastText ha demostrado recientemente ser el estado del arte para incrustaciones de palabras y tareas de clasificación de texto en muchos conjuntos de datos. Es muy fácil de usar y ultrarrápido en comparación con otros modelos de incrustación de palabras.

En este artículo, exploramos brevemente cómo encontrar similitudes semánticas entre diferentes palabras creando incrustaciones de palabras usando FastText. La segunda parte del artículo explica cómo realizar la clasificación de texto a través de la biblioteca FastText.