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 se puede usar la biblioteca spaCy de Python para realizar partes del etiquetado de voz y el reconocimiento de entidades con nombre. En este artículo, demostraré cómo realizar un análisis de sentimientos utilizando datos de Twitter utilizando la biblioteca Scikit-Learn.

    El análisis de sentimientos se refiere a analizar una opinión o sentimientos sobre algo utilizando datos como texto o imágenes, sobre casi cualquier cosa. El análisis de 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 opinión pública, por ejemplo, entrevistas públicas, sondeos 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 conocer la opinión pública.

    En este artículo, veremos cómo podemos realizar análisis de sentimiento de datos de texto.

    Definición del problema

    Dados 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 típica de aprendizaje supervisado en la que, dada una cadena de texto, tenemos que categorizar la cadena de texto en categorías predefinidas.

    Solución

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

    Importación de las bibliotecas necesarias

    El primer paso como siempre es importar las bibliotecas necesarias:

    import numpy as np 
    import pandas as pd 
    import re
    import nltk 
    import matplotlib.pyplot as plt
    %matplotlib inline
    

    Nota: Todas las secuencias de comandos del artículo se han ejecutado con Jupyter Notebook.

    Importar 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, usaremos Pandas read_csv función, 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)
    

    Primero veamos cómo se ve el conjunto de datos usando 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. Ejecute 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 
    

    Primero veamos la cantidad de tweets de 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 de cada aerolínea. United Airline tiene el mayor número de tweets, es decir, el 26%, seguida de US Airways (20%).

    Veamos ahora la distribución de sentimientos en todos los tweets. Ejecute el siguiente script:

    airline_tweets.airline_sentiment.value_counts().plot(kind='pie', autopct="%1.0f%%", colors=["red", "yellow", "green"])
    

    La salida del script anterior se ve así:

    En el resultado, 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 por el resultado que para casi todas las aerolíneas, la mayoría de los tweets son negativos, seguidos de 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 opinión. Ejecute el siguiente script:

    import seaborn as sns
    
    sns.barplot(x='airline_sentiment', y='airline_sentiment_confidence' , data=airline_tweets)
    

    La salida del script anterior se ve así:

    En la salida, puede ver que el nivel de confianza para los tweets negativos es más alto en comparación con los tweets positivos y neutrales.

    Suficiente del 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 jerga y signos de puntuación. Necesitamos limpiar nuestros tweets antes de que puedan usarse para entrenar el modelo de Machine Learning. Sin embargo, antes de limpiar los tweets, dividamos nuestro conjunto de datos en conjuntos de características y etiquetas.

    Nuestro conjunto de funciones constará únicamente de tweets. Si miramos nuestro conjunto de datos, la undécima columna contiene el texto del tweet. Tenga en cuenta que el índice de la columna será 10, ya que las columnas de pandas siguen el esquema de indexación de base cero donde la primera columna se llama columna 0. 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 iloc método fuera del marco de datos de pandas.

    Ejecute el siguiente script:

    features = airline_tweets.iloc[:, 10].values
    labels = airline_tweets.iloc[:, 1].values
    

    Una vez que dividimos los datos en funciones y conjunto de entrenamiento, podemos preprocesar los datos para limpiarlos. Para hacerlo, usaremos expresiones regulares. Para estudiar más sobre las expresiones regulares, consulte 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'^bs+', '', 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 usando el re.sub(r's+[a-zA-Z]s+', ' ', processed_feature) expresión regular. Por ejemplo, si eliminamos un carácter especial ' desde Jack's y reemplazarlo con espacio, nos quedamos con Jack s. aquí s no 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 simples usando re.sub(r's+', ' ', processed_feature, flags=re.I) regex. Además, si su cadena de texto está en formato de bytes, un carácter b se agrega con la cadena. El script anterior elimina eso usando la expresión regular re.sub(r'^bs+', '', processed_feature).

    Finalmente, el texto se convierte a minúsculas usando el lower() función.

    Representar texto en forma numérica

    Los algoritmos estadísticos utilizan las matemáticas para entrenar modelos de Machine Learning. Sin embargo, las matemáticas solo funcionan con números. Para que los algoritmos estadísticos funcionen con texto, primero tenemos que convertir el texto en números. Para hacerlo, existen tres enfoques principales, es decir, Bag of Words, 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, tiene tres documentos:

    • Doc1 = “Me gusta jugar al fútbol”
    • Doc2 = “Es un buen juego”
    • Doc3 = “Prefiero el fútbol al rugby”

    En el enfoque de 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 del 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 el enfoque de 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 un documento individual 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. Pueden calcularse 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 usando la biblioteca Scikit-Learn

    Por suerte para nosotros, Python Scikit-Learn biblioteca contiene el TfidfVectorizer clase que se puede utilizar para convertir características de texto en vectores de características TF-IDF. La siguiente secuencia de comandos realiza esto:

    from nltk.corpus import stopwords
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    vectorizer = TfidfVectorizer (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 el max_features debe ser 2500, lo que significa que solo utiliza las 2500 palabras que aparecen con mayor frecuencia para crear un vector de características de bolsa de palabras. Las palabras que aparecen con menos frecuencia no son muy útiles para la clasificación.

    Similar, max_df especifica que solo se utilizarán aquellas palabras que se presenten 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. Similar, min-df se establece en 7, lo que muestra que incluyen palabras que aparecen en al menos 7 documentos.

    División de datos en conjuntos de prueba y entrenamiento

    En la sección anterior, convertimos los datos en forma numérica. Como último paso antes de entrenar nuestros algoritmos, necesitamos dividir nuestros datos en conjuntos de entrenamiento y prueba. El conjunto de entrenamiento se utilizará para entrenar el algoritmo, mientras que el conjunto de prueba se utilizará para evaluar el rendimiento del modelo de Machine Learning.

    Ejecute 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 el train_test_split clase de la sklearn.model_selection módulo para dividir nuestros datos en conjunto de entrenamiento y prueba. El método toma el conjunto de características como primer parámetro, el conjunto de etiquetas como segundo parámetro y un valor para el test_size parámetro. Especificamos un valor de 0,2 para test_size lo que significa que nuestro conjunto de datos se dividirá en dos conjuntos de 80% y 20% de datos. Usaremos el conjunto de datos del 80% para el entrenamiento y el conjunto de datos del 20% para las pruebas.

    Entrenando el modelo

    Una vez que los datos se dividen en conjuntos de entrenamiento y prueba, se pueden usar algoritmos de Machine Learning para aprender de los datos de entrenamiento. Puede utilizar cualquier algoritmo de Machine Learning. Sin embargo, usaremos el algoritmo Random Forest, debido a su capacidad para actuar sobre datos no normalizados.

    los sklearn.ensemble módulo contiene el RandomForestClassifier clase que se puede utilizar para entrenar el modelo de Machine Learning mediante el algoritmo de bosque aleatorio. Para hacerlo, debemos llamar al fit método en el RandomForestClassifier class y pasarle nuestras características y etiquetas de entrenamiento, como parámetros. Mira el siguiente guión:

    from sklearn.ensemble import RandomForestClassifier
    
    text_classifier = RandomForestClassifier(n_estimators=200, random_state=0)
    text_classifier.fit(X_train, y_train)
    

    Hacer predicciones y evaluar el modelo

    Una vez que se ha entrenado el modelo, el último paso es realizar predicciones sobre el modelo. Para hacerlo, debemos llamar al predict método en el objeto de la RandomForestClassifier clase que usamos para el entrenamiento. Mira el siguiente guión:

    predictions = text_classifier.predict(X_test)
    

    Finalmente, para evaluar el rendimiento de los modelos de Machine Learning, podemos utilizar métricas de clasificación como confusión metrix, Medida F1, precisión, etc.

    Para encontrar los valores de estas métricas, podemos usar classification_report, confusion_matrixy accuracy_score utilidades del sklearn.metrics biblioteca. Mira el siguiente guión:

    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 del script 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
    

    En la salida, puede ver que nuestro algoritmo logró 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 los tweets públicos sobre seis aerolíneas estadounidenses y logramos una precisión de alrededor del 75%. Le recomendaría que pruebe y utilice algún otro algoritmo de Machine Learning, como regresión logística, SVM o KNN, y vea 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.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *