Cree un programa de clasificación de texto: un tutorial de PNL
Publicado: 2022-03-11El aprendizaje profundo es una tecnología que se ha convertido en una parte esencial de los flujos de trabajo de aprendizaje automático. Aprovechando las mejoras de la potencia informática paralela y las herramientas de soporte, las redes neuronales complejas y profundas que alguna vez fueron poco prácticas ahora se están volviendo viables.
La aparición de bibliotecas poderosas y accesibles como Tensorflow, Torch y Deeplearning4j también ha abierto el desarrollo a usuarios más allá de la academia y los departamentos de investigación de las grandes empresas de tecnología. Como testimonio de su creciente ubicuidad, empresas como Huawei y Apple ahora incluyen procesadores dedicados optimizados para el aprendizaje profundo en sus dispositivos más nuevos para potenciar las aplicaciones de aprendizaje profundo.
El aprendizaje profundo ha demostrado su poder en muchos dominios. En particular, AlphaGo de Google pudo derrotar a los jugadores humanos en un juego de Go, un juego cuya alucinante complejidad alguna vez se consideró una barrera casi insuperable para las computadoras en su competencia contra los jugadores humanos. El proyecto Flow Machines de Sony ha desarrollado una red neuronal que puede componer música al estilo de músicos famosos del pasado. FaceID, una función de seguridad desarrollada por Apple, utiliza el aprendizaje profundo para reconocer el rostro del usuario y realizar un seguimiento de los cambios en el rostro del usuario a lo largo del tiempo.
En este artículo, aplicaremos el aprendizaje profundo a dos de mis temas favoritos: el procesamiento del lenguaje natural y el vino. Construiremos un modelo para comprender las reseñas de vino en lenguaje natural realizadas por expertos y deduciremos la variedad del vino que están reseñando.
Aprendizaje profundo para PNL
El aprendizaje profundo se ha utilizado ampliamente en el procesamiento del lenguaje natural (PNL) porque es muy adecuado para aprender la estructura subyacente compleja de una oración y la proximidad semántica de varias palabras. Por ejemplo, el estado actual del arte para el análisis de sentimientos utiliza el aprendizaje profundo para capturar conceptos lingüísticos difíciles de modelar, como negaciones y sentimientos mixtos.
El aprendizaje profundo tiene varias ventajas sobre otros algoritmos para PNL:
- Modelos flexibles: los modelos de aprendizaje profundo son mucho más flexibles que otros modelos de ML. Podemos experimentar fácilmente con diferentes estructuras, agregando y eliminando capas según sea necesario. Los modelos de aprendizaje profundo también permiten construir modelos con resultados flexibles. La flexibilidad es clave para desarrollar modelos que sean adecuados para comprender estructuras lingüísticas complejas. También es esencial para desarrollar aplicaciones de NLP como traducciones, chatbots y aplicaciones de texto a voz.
- Se requiere menos conocimiento del dominio: si bien es cierto que se necesita cierto conocimiento del dominio e intuición para desarrollar un buen modelo de aprendizaje profundo, la capacidad de los algoritmos de aprendizaje profundo para aprender jerarquías de funciones por sí solos significa que un desarrollador no necesita un conocimiento tan profundo del espacio de problemas para desarrollar algoritmos de PNL de aprendizaje profundo. Para un espacio de problemas tan complejo como el lenguaje natural, esta es una ventaja muy bienvenida.
- Aprendizaje continuo más fácil: los algoritmos de aprendizaje profundo son fáciles de entrenar a medida que ingresan nuevos datos. Algunos algoritmos de aprendizaje automático requieren que todo el conjunto de datos se envíe a través del modelo para actualizarlo, lo que presentaría un problema para grandes conjuntos de datos en vivo.
El problema de hoy
Hoy, construiremos un algoritmo de aprendizaje profundo para determinar la variedad del vino que se está revisando en función del texto de revisión. Usaremos el conjunto de datos de la revista sobre vinos en https://www.kaggle.com/zynicide/wine-reviews, proporcionado por el usuario de Kaggle, zackthoutt .
Conceptualmente, la pregunta es, ¿podemos tomar una reseña de vino como...
Los aromas incluyen frutas tropicales, retama, azufre y hierba seca. En boca no es demasiado expresivo, ofrece manzana sin madurar, cítricos y salvia seca junto con una acidez enérgica.
…y reconocer que se trata de un blend blanco? Algunos entusiastas del vino pueden reconocer signos reveladores de vinos blancos como manzana, cítricos y una acidez pronunciada, pero ¿podemos entrenar nuestra red neuronal para reconocer estas señales? Además, ¿podemos entrenar nuestra red neuronal para que reconozca las diferencias sutiles entre una revisión de mezcla blanca y una revisión de pinot grigio?
Algoritmos similares
El problema con el que estamos trabajando hoy es esencialmente un problema de clasificación de PNL. Hay varios algoritmos de clasificación de PNL que se han aplicado a varios problemas en PNL. Por ejemplo, Naive Bayes se ha utilizado en varios algoritmos de detección de correo no deseado y se han utilizado máquinas de vectores de soporte (SVM) para clasificar textos como notas de progreso en instituciones de atención médica. Sería interesante implementar una versión simple de estos algoritmos para que sirvan como base para nuestro modelo de aprendizaje profundo.
bayesiana ingenua
Una implementación popular de Naive Bayes para NLP implica preprocesar el texto usando TF-IDF y luego ejecutar Naive Bayes multinomial en las salidas preprocesadas. Esto permite que el algoritmo se ejecute en las palabras más destacadas dentro de un documento. Podemos implementar el ingenuo Bayes de la siguiente manera:
import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfTransformer df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() varietal_list = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = np.array(varietal_list) count_vect = CountVectorizer() x_train_counts = count_vect.fit_transform(description_list) tfidf_transformer = TfidfTransformer() x_train_tfidf = tfidf_transformer.fit_transform(x_train_counts) train_x, test_x, train_y, test_y = train_test_split(x_train_tfidf, varietal_list, test_size=0.3) clf = MultinomialNB().fit(train_x, train_y) y_score = clf.predict(test_x) n_right = 0 for i in range(len(y_score)): if y_score[i] == test_y[i]: n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
Ejecute el código anterior y debería ver algo como lo siguiente: 73.56%

Teniendo en cuenta que estamos viendo 10 clases, este es un buen resultado.
También podemos usar la máquina de vectores de soporte y ver cómo funciona. Para ver cómo funciona, simplemente reemplace la definición del clasificador con
clf = SVC(kernel='linear').fit(train_x, train_y)
Ejecute esto y debería ver el siguiente resultado:
Precisión: 80,66%
Tampoco está mal.
Veamos si podemos construir un modelo de aprendizaje profundo que pueda superar o al menos igualar estos resultados. Si logramos eso, sería una gran indicación de que nuestro modelo de aprendizaje profundo es efectivo al menos para replicar los resultados de los modelos populares de aprendizaje automático informados por la experiencia del dominio.
Construyendo el modelo
Hoy usaremos Keras con Tensorflow para construir nuestro modelo. Keras es una biblioteca de Python que facilita mucho la creación de modelos de aprendizaje profundo en comparación con la interfaz de nivel relativamente bajo de la API de Tensorflow. Además de las capas densas, también usaremos capas incrustadas y convolucionales para aprender la información semántica subyacente de las palabras y los posibles patrones estructurales dentro de los datos.
Limpieza de datos
Primero, tendremos que reestructurar los datos de manera que nuestra red neuronal pueda procesarlos y comprenderlos fácilmente. Podemos hacer esto reemplazando las palabras con números de identificación únicos. Combinado con un vector de incrustación, podemos representar las palabras de una manera flexible y semánticamente sensible.
En la práctica, querremos ser un poco más inteligentes con este preprocesamiento. Tendría sentido centrarse en las palabras de uso común y también filtrar las palabras de uso más común (p. ej., el, este, a).
Podemos implementar esta funcionalidad usando Defaultdict y NLTK. Escriba el siguiente código en un módulo de Python separado. Lo coloqué en lib/get_top_x_words.py
.
from nltk import word_tokenize from collections import defaultdict def count_top_x_words(corpus, top_x, skip_top_n): count = defaultdict(lambda: 0) for c in corpus: for w in word_tokenize(c): count[w] += 1 count_tuples = sorted([(w, c) for w, c in count.items()], key=lambda x: x[1], reverse=True) return [i[0] for i in count_tuples[skip_top_n: skip_top_n + top_x]] def replace_top_x_words_with_vectors(corpus, top_x): topx_dict = {top_x[i]: i for i in range(len(top_x))} return [ [topx_dict[w] for w in word_tokenize(s) if w in topx_dict] for s in corpus ], topx_dict def filter_to_top_x(corpus, n_top, skip_n_top=0): top_x = count_top_x_words(corpus, n_top, skip_n_top) return replace_top_x_words_with_vectors(corpus, top_x)
Ahora estamos listos para construir el modelo. Queremos una capa de incrustación, una capa convolucional y una capa densa para aprovechar todas las funciones de aprendizaje profundo que pueden ser útiles para nuestra aplicación. Con Keras podemos construir el modelo de forma muy sencilla:
from keras.models import Sequential from keras.layers import Dense, Conv1D, Flatten from keras.layers.embeddings import Embedding from keras.preprocessing import sequence from keras.utils import to_categorical import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from lib.get_top_xwords import filter_to_top_x df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() mapped_list, word_list = filter_to_top_x(description_list, 2500, 10) varietal_list_o = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = to_categorical(varietal_list_o) max_review_length = 150 mapped_list = sequence.pad_sequences(mapped_list, maxlen=max_review_length) train_x, test_x, train_y, test_y = train_test_split(mapped_list, varietal_list, test_size=0.3) max_review_length = 150 embedding_vector_length = 64 model = Sequential() model.add(Embedding(2500, embedding_vector_length, input_length=max_review_length)) model.add(Conv1D(50, 5)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(max(varietal_list_o) + 1, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, epochs=3, batch_size=64) y_score = model.predict(test_x) y_score = [[1 if i == max(sc) else 0 for i in sc] for sc in y_score] n_right = 0 for i in range(len(y_score)): if all(y_score[i][j] == test_y[i][j] for j in range(len(y_score[i]))): n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
Ejecute el código y debería ver el siguiente resultado.
Precisión: 77,20%
Recuerde que la precisión para Naive Bayes y SVC fue del 73,56 % y del 80,66 %, respectivamente. Por lo tanto, nuestra red neuronal se mantiene firme frente a algunos de los métodos de clasificación de texto más comunes que existen.
Conclusión
Hoy, cubrimos la construcción de un modelo de clasificación de aprendizaje profundo para analizar las reseñas de vinos.
Descubrimos que podíamos construir un modelo que podía competir y superar a algunos de los otros algoritmos de aprendizaje automático. ¡Esperamos que se sienta inspirado para usar esta información para crear aplicaciones que analicen conjuntos de datos más complejos y generen resultados más complejos!
Nota: Puede encontrar el código que usé para este artículo en GitHub.
Lecturas adicionales en el blog de ingeniería de Toptal:
- Un significado más profundo: modelado de temas en Python
- Cómo construir un bot de análisis de sentimiento de correo electrónico: un tutorial de PNL