Breaking

Post Top Ad

Your Ad Spot

viernes, 14 de junio de 2019

Python para PNL: Análisis de sentimiento con Scikit-Learn

Este es el quinto artículo de la serie de artículos sobre PNL para Python. En mi artículo anterior , expliqué cómo la biblioteca spaCy de Python se puede usar para realizar partes de etiquetado de voz y reconocimiento de entidades nombradas. En este artículo, demostraré cómo hacer un análisis de sentimientos utilizando los datos de Twitter utilizando la biblioteca Scikit-Learn.
El análisis de sentimientos se refiere al análisis de una opinión o sentimientos sobre algo que usa datos como texto o imágenes, con respecto a casi cualquier cosa. El análisis del sentimiento ayuda a las empresas en su proceso de toma de decisiones. Por ejemplo, si el sentimiento público hacia un producto no es tan bueno, una empresa puede intentar modificar el producto o detener la producción por completo para evitar pérdidas.
Hay muchas fuentes de sentimiento público, por ejemplo, entrevistas públicas, encuestas de opinión, encuestas, etc. Sin embargo, con más y más personas que se unen a las plataformas de redes sociales, los sitios web como Facebook y Twitter pueden analizarse para el sentimiento público.
En este artículo, veremos cómo podemos realizar un análisis de sentimiento de los datos de texto.

Definición del problema

Teniendo en cuenta los tweets sobre seis aerolíneas estadounidenses, la tarea es predecir si un tweet contiene un sentimiento positivo, negativo o neutral sobre la aerolínea. Esta es una tarea de aprendizaje supervisado típica donde, dada una cadena de texto, tenemos que clasificar la cadena de texto en categorías predefinidas.

Solución

Para resolver este problema, seguiremos la línea típica de aprendizaje automático. Primero importaremos las bibliotecas requeridas y el conjunto de datos. Luego, realizaremos un análisis exploratorio de los datos para ver si podemos encontrar alguna tendencia en el conjunto de datos. A continuación, realizaremos el preprocesamiento de texto para convertir los datos textuales en datos numéricos que pueden ser utilizados por un algoritmo de aprendizaje automático. Finalmente, usaremos algoritmos de aprendizaje automático para entrenar y probar nuestros modelos de análisis de sentimientos.

Importando las bibliotecas requeridas

El primer paso como siempre es importar las bibliotecas requeridas:
import numpy as np  
import pandas as pd  
import re  
import nltk  
import matplotlib.pyplot as plt  
%matplotlib inline
Nota: todos los scripts en el artículo se han ejecutado utilizando el portátil Jupyter.

Importando el conjunto de datos

El conjunto de datos que vamos a utilizar para este artículo está disponible gratuitamente en este enlace de Github .
Para importar el conjunto de datos, utilizaremos la read_csvfunción Pandas , como se muestra a continuación:
data_source_url = "https://raw.githubusercontent.com/kolaveridi/kaggle-Twitter-US-Airline-Sentiment-/master/Tweets.csv"  
airline_tweets = pd.read_csv(data_source_url)  
Veamos primero cómo se ve el conjunto de datos utilizando el head()método:
airline_tweets.head()  
La salida se ve así:

Análisis de los datos

Exploremos un poco el conjunto de datos para ver si podemos encontrar alguna tendencia. Pero antes de eso, cambiaremos el tamaño predeterminado de la parcela para tener una mejor vista de las parcelas. Ejecuta el siguiente script:
plot_size = plt.rcParams["figure.figsize"]  
print(plot_size[0])  
print(plot_size[1])

plot_size[0] = 8  
plot_size[1] = 6  
plt.rcParams["figure.figsize"] = plot_size  
Veamos primero el número de tweets para cada aerolínea. Trazaremos un gráfico circular para eso:
airline_tweets.airline.value_counts().plot(kind='pie', autopct='%1.0f%%')  
En la salida, puede ver el porcentaje de tweets públicos para cada aerolínea. United Airline tiene el mayor número de tweets, es decir, un 26%, seguido de US Airways (20%).
Veamos ahora la distribución de los sentimientos en todos los tweets. Ejecuta el siguiente script:
airline_tweets.airline_sentiment.value_counts().plot(kind='pie', autopct='%1.0f%%', colors=["red", "yellow", "green"])  
La salida de la secuencia de comandos anterior se ve así:
Desde la salida, puede ver que la mayoría de los tweets son negativos (63%), seguidos de los tweets neutrales (21%) y luego los tweets positivos (16%).
A continuación, veamos la distribución del sentimiento para cada aerolínea individual,
airline_sentiment = airline_tweets.groupby(['airline', 'airline_sentiment']).airline_sentiment.count().unstack()  
airline_sentiment.plot(kind='bar')  
La salida se ve así:
Es evidente a partir de la salida que para la mayoría de las aerolíneas, la mayoría de los tweets son negativos, seguidos de los tweets neutrales y positivos. Virgin America es probablemente la única aerolínea donde la proporción de los tres sentimientos es algo similar.
Finalmente, usemos la biblioteca Seaborn para ver el nivel de confianza promedio de los tweets que pertenecen a tres categorías de opiniones. Ejecuta el siguiente script:
import seaborn as sns

sns.barplot(x='airline_sentiment', y='airline_sentiment_confidence' , data=airline_tweets)  
La salida de la secuencia de comandos anterior se ve así:
Desde la salida, puede ver que el nivel de confianza para los tweets negativos es mayor en comparación con los tweets positivos y neutrales.
Una vez finalizado el análisis exploratorio de datos, nuestro siguiente paso es realizar un procesamiento previo de los datos y luego convertir los datos numéricos en datos de texto como se muestra a continuación.

Limpieza de datos

Los tweets contienen muchas palabras de argot y signos de puntuación. Necesitamos limpiar nuestros tweets antes de que puedan usarse para entrenar el modelo de aprendizaje automático. Sin embargo, antes de limpiar los tweets, dividamos nuestro conjunto de datos en conjuntos de características y etiquetas.
Nuestro conjunto de características consistirá en tweets solamente. Si observamos nuestro conjunto de datos, la 11ª columna contiene el texto del tweet. Tenga en cuenta que el índice de la columna será 10, ya que las columnas de pandas siguen un esquema de indexación de base cero donde la primera columna se llama 0ª columna. Nuestro conjunto de etiquetas consistirá en el sentimiento del tweet que tenemos que predecir. El sentimiento del tweet está en la segunda columna (índice 1). Para crear una característica y un conjunto de etiquetas, podemos usar el ilocmétodo fuera del marco de datos de pandas.
Ejecuta el siguiente script:
features = airline_tweets.iloc[:, 10].values  
labels = airline_tweets.iloc[:, 1].values  
Una vez que dividimos los datos en características y conjunto de entrenamiento, podemos preprocesar los datos para limpiarlos. Para ello, utilizaremos expresiones regulares. Para estudiar más sobre las expresiones regulares, eche un vistazo a este artículo sobre expresiones regulares .
processed_features = []

for sentence in range(0, len(features)):  
    # Remove all the special characters
    processed_feature = re.sub(r'\W', ' ', str(features[sentence]))

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

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

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

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

    # Converting to Lowercase
    processed_feature = processed_feature.lower()

    processed_features.append(processed_feature)
En el script anterior, comenzamos eliminando todos los caracteres especiales de los tweets. La expresión regular re.sub(r'\W', ' ', str(features[sentence]))hace eso.
A continuación, eliminamos todos los caracteres individuales que quedan como resultado de eliminar el carácter especial utilizando la re.sub(r'\s+[a-zA-Z]\s+', ' ', processed_feature)expresión regular. Por ejemplo, si quitamos carácter especial 'desde Jack'sy reemplazarlo con el espacio, nos queda Jack sAquí sno tiene significado, así que lo eliminamos reemplazando todos los caracteres individuales con un espacio.
Sin embargo, si reemplazamos todos los caracteres individuales con espacio, se crean múltiples espacios. Por lo tanto, reemplazamos todos los espacios múltiples con espacios individuales usando re.sub(r'\s+', ' ', processed_feature, flags=re.I)expresiones regulares. Además, si la cadena de texto está en formato de bytes, bse añade un carácter con la cadena. El script anterior elimina eso usando la expresión regular re.sub(r'^b\s+', '', processed_feature).
Finalmente, el texto se convierte a minúsculas usando la lower()función.

Representar texto en forma numérica

Los algoritmos estadísticos utilizan las matemáticas para entrenar modelos de aprendizaje automático. Sin embargo, las matemáticas solo funcionan con números. Para hacer que los algoritmos estadísticos funcionen con texto, primero tenemos que convertir texto en números. Para hacerlo, existen tres enfoques principales, es decir, Bolsa de palabras, TF-IDF y Word2Vec. En esta sección, discutiremos la bolsa de palabras y el esquema TF-IDF.
Bolsa de palabras
El esquema de bolsa de palabras es la forma más sencilla de convertir texto en números.
Por ejemplo, usted tiene tres documentos:
  • Doc1 = "Me gusta jugar al fútbol"
  • Doc2 = "Es un buen juego"
  • Doc3 = "Prefiero el fútbol sobre el rugby"
En la bolsa de palabras, el primer paso es crear un vocabulario de todas las palabras únicas. Para los tres documentos anteriores, nuestro vocabulario será:
Vocab = [I, like, to, play, football, it, is, a, good, game, prefer, over, rugby]  
El siguiente paso es convertir cada documento en un vector de características utilizando el vocabulario. La longitud de cada vector de características es igual a la longitud del vocabulario. La frecuencia de la palabra en el documento reemplazará la palabra real en el vocabulario. Si no se encuentra una palabra en el vocabulario en el documento correspondiente, el vector de características del documento tendrá cero en ese lugar. Por ejemplo, para Doc1, el vector de características se verá así:
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
TF-IDF
En la bolsa de palabras, cada palabra tiene el mismo peso. La idea detrás del enfoque TF-IDF es que las palabras que aparecen menos en todos los documentos y más en los documentos individuales contribuyen más a la clasificación.
TF-IDF es una combinación de dos términos. Frecuencia de término y frecuencia de documento inverso. Se pueden calcular como:
TF  = (Frequency of a word in the document)/(Total words in the document)

IDF = Log((Total number of docs)/(Number of docs containing the word))  
TF-IDF utilizando la biblioteca de Scikit-Learn
Afortunadamente para nosotros, la biblioteca Scikit-Learn de Python contiene la TfidfVectorizerclase que se puede usar para convertir características de texto en vectores de características TF-IDF. El siguiente script realiza esto:
from nltk.corpus import stopwords  
from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(max_features=2500, min_df=7, max_df=0.8, stop_words=stopwords.words('english'))  
processed_features = vectorizer.fit_transform(processed_features).toarray()  
En el código anterior, definimos que max_featuresdebería ser 2500, lo que significa que solo usa las 2500 palabras que aparecen con mayor frecuencia para crear una bolsa de palabras con el vector de características. Las palabras que aparecen con menos frecuencia no son muy útiles para la clasificación.
Del mismo modo, max_dfespecifica que solo se usan aquellas palabras que aparecen en un máximo del 80% de los documentos. Las palabras que aparecen en todos los documentos son demasiado comunes y no son muy útiles para la clasificación. Del mismo modo, min-dfse establece en 7, que muestra que incluyen palabras que aparecen en al menos 7 documentos.

División de datos en conjuntos de entrenamiento y prueba

En la sección anterior, convertimos los datos a la forma numérica. Como último paso antes de entrenar nuestros algoritmos, debemos dividir nuestros datos en conjuntos de entrenamiento y pruebas. El conjunto de entrenamiento se utilizará para entrenar el algoritmo, mientras que el conjunto de pruebas se utilizará para evaluar el rendimiento del modelo de aprendizaje automático.
Ejecuta el siguiente código:
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(processed_features, labels, test_size=0.2, random_state=0)  
En el código anterior, usamos la train_test_splitclase del sklearn.model_selectionmódulo para dividir nuestros datos en un conjunto de entrenamiento y pruebas. El método toma el conjunto de características como el primer parámetro, la etiqueta establecida como el segundo parámetro y un valor para el test_sizeparámetro. Especificamos un valor de 0.2, lo test_sizeque significa que nuestro conjunto de datos se dividirá en dos conjuntos de datos de 80% y 20%. Usaremos el conjunto de datos del 80% para la capacitación y el conjunto de datos del 20% para las pruebas.

Entrenando el modelo

Una vez que los datos se dividen en entrenamiento y conjunto de pruebas, se pueden utilizar algoritmos de aprendizaje automático para aprender de los datos de entrenamiento. Puede utilizar cualquier algoritmo de aprendizaje automático. Sin embargo, usaremos el algoritmo de bosque aleatorio , debido a su capacidad para actuar sobre datos no normalizados.
El sklearn.ensemblemódulo contiene la RandomForestClassifierclase que se puede usar para entrenar el modelo de aprendizaje automático utilizando el algoritmo de bosque aleatorio. Para hacerlo, necesitamos llamar al fitmétodo en la RandomForestClassifierclase y pasarle nuestras características de entrenamiento y etiquetas, como parámetros. Mira el siguiente script:
from sklearn.ensemble import RandomForestClassifier

text_classifier = RandomForestClassifier(n_estimators=200, random_state=0)  
text_classifier.fit(X_train, y_train)  

Haciendo predicciones y evaluando el modelo

Una vez que el modelo ha sido entrenado, el último paso es hacer predicciones sobre el modelo. Para hacerlo, necesitamos llamar al predictmétodo en el objeto de la RandomForestClassifierclase que usamos para la capacitación. Mira el siguiente script:
predictions = text_classifier.predict(X_test)  
Finalmente, para evaluar el rendimiento de los modelos de aprendizaje automático, podemos usar métricas de clasificación, como una metrix de confusión , medida de F1 , precisión, etc.
Para encontrar los valores de estos parámetros, podemos utilizar classification_reportconfusion_matrixaccuracy_scorelas utilidades de la sklearn.metricsbiblioteca. Mira el siguiente script:
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score

print(confusion_matrix(y_test,predictions))  
print(classification_report(y_test,predictions))  
print(accuracy_score(y_test, predictions))  
La salida de la secuencia de comandos anterior se ve así:
[[1724  101   45]
 [ 329  237   48]
 [ 142   58  244]]
              precision    recall  f1-score   support

    negative       0.79      0.92      0.85      1870
     neutral       0.60      0.39      0.47       614
    positive       0.72      0.55      0.62       444

   micro avg       0.75      0.75      0.75      2928
   macro avg       0.70      0.62      0.65      2928
weighted avg       0.74      0.75      0.73      2928

0.7530737704918032  
Desde la salida, puede ver que nuestro algoritmo alcanzó una precisión de 75.30.

Conclusión

El análisis de sentimientos es una de las tareas de PNL que se realizan con más frecuencia, ya que ayuda a determinar la opinión pública general sobre un tema determinado.
En este artículo, vimos cómo las diferentes bibliotecas de Python contribuyen a realizar el análisis de sentimientos. Realizamos un análisis de tweets públicos con respecto a seis aerolíneas estadounidenses y alcanzamos una precisión de alrededor del 75%. Le recomendaría probar y utilizar algún otro algoritmo de aprendizaje automático, como regresión logística , SVM o KNN y ver si puede obtener mejores resultados.
En el próximo artículo , mostraré cómo realizar el modelado de temas con Scikit-Learn, que es una técnica no supervisada para analizar grandes volúmenes de datos de texto agrupando los documentos en grupos.

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas