Clasificaci贸n de texto con Python y Scikit-Learn

    Introducci贸n

    La clasificaci贸n de texto es una de las tareas m谩s importantes en el procesamiento del lenguaje natural. Es el proceso de clasificar cadenas de texto o documentos en diferentes categor铆as, seg煤n el contenido de las cadenas. La clasificaci贸n de texto tiene una variedad de aplicaciones, como detectar la opini贸n del usuario a partir de un tweet, clasificar un correo electr贸nico como spam o ham, clasificar publicaciones de blog en diferentes categor铆as, etiquetar autom谩ticamente las consultas de los clientes, etc.

    En este art铆culo, veremos un ejemplo del mundo real de clasificaci贸n de texto. Entrenaremos un modelo de Machine Learning capaz de predecir si una cr铆tica de pel铆cula determinada es positiva o negativa. Este es un ejemplo cl谩sico de an谩lisis sentimental en el que los sentimientos de las personas hacia una entidad en particular se clasifican en diferentes categor铆as.

    Conjunto de datos

    El conjunto de datos que vamos a utilizar para este art铆culo se puede descargar del Grupo de procesamiento del lenguaje natural de Cornell. El conjunto de datos consta de un total de 2000 documentos. La mitad de los documentos contienen cr铆ticas positivas sobre una pel铆cula, mientras que la mitad restante contiene cr铆ticas negativas. Se pueden encontrar m谩s detalles sobre el conjunto de datos en este enlace.

    Descomprima o extraiga el conjunto de datos una vez que lo descargue. Abra la carpeta “txt_sentoken”. La carpeta contiene dos subcarpetas: “neg” y “pos”. Si abre estas carpetas, puede ver los documentos de texto que contienen rese帽as de pel铆culas.

    An谩lisis de sentimiento con Scikit-Learn

    Ahora que hemos descargado los datos, es hora de ver alguna acci贸n. En esta secci贸n, realizaremos una serie de pasos necesarios para predecir los sentimientos de las rese帽as de diferentes pel铆culas. Estos pasos se pueden utilizar para cualquier tarea de clasificaci贸n de texto. Usaremos la biblioteca Scikit-Learn de Python para el Machine Learning para entrenar un modelo de clasificaci贸n de texto.

    Los siguientes son los pasos necesarios para crear un modelo de clasificaci贸n de texto en Python:

    • Importaci贸n de bibliotecas
    • Importando el conjunto de datos
    • Preprocesamiento de texto
    • Convertir texto en n煤meros
    • Conjuntos de entrenamiento y prueba
    • Entrenamiento del modelo de clasificaci贸n de texto y predicci贸n del sentimiento
    • Evaluaci贸n del modelo
    • Guardar y cargar el modelo

    Importaci贸n de bibliotecas

    Ejecute el siguiente script para importar las bibliotecas necesarias:

    import numpy as np
    import re
    import nltk
    from sklearn.datasets import load_files
    nltk.download('stopwords')
    import pickle
    from nltk.corpus import stopwords
    

    Importar el conjunto de datos

    Usaremos el load_files funci贸n de la sklearn_datasets biblioteca para importar el conjunto de datos a nuestra aplicaci贸n. los load_files La funci贸n divide autom谩ticamente el conjunto de datos en conjuntos de datos y de destino. Por ejemplo, en nuestro caso, le pasaremos la ruta al directorio “txt_sentoken”. los load_files tratar谩 cada carpeta dentro de la carpeta “txt_sentoken” como una categor铆a ya todos los documentos dentro de esa carpeta se les asignar谩 su categor铆a correspondiente.

    Ejecute el siguiente script para ver load_files funci贸n en acci贸n:

    movie_data = load_files(r"D:txt_sentoken")
    X, y = movie_data.data, movie_data.target
    

    En el gui贸n de arriba, el load_files La funci贸n carga los datos de las carpetas “neg” y “pos” en el X variable, mientras que las categor铆as de destino se almacenan en y. Aqu铆 X es una lista de 2000 elementos de tipo cadena donde cada elemento corresponde a la revisi贸n de un solo usuario. Similar, y es una matriz numerosa de tama帽o 2000. Si imprime y en la pantalla, ver谩 una matriz de 1 y 0. Esto se debe a que, para cada categor铆a, load_files La funci贸n agrega un n煤mero a la matriz num茅rica de destino. Tenemos dos categor铆as: “neg” y “pos”, por lo tanto, se han agregado 1 y 0 a la matriz de destino.

    Preprocesamiento de texto

    Una vez que se ha importado el conjunto de datos, el siguiente paso es preprocesar el texto. El texto puede contener n煤meros, caracteres especiales y espacios no deseados. Dependiendo del problema que enfrentemos, es posible que necesitemos o no eliminar estos n煤meros y caracteres especiales del texto. Sin embargo, en aras de la explicaci贸n, eliminaremos todos los caracteres especiales, n煤meros y espacios no deseados de nuestro texto. Ejecute el siguiente script para preprocesar los datos:

    documents = []
    
    from nltk.stem import WordNetLemmatizer
    
    stemmer = WordNetLemmatizer()
    
    for sen in range(0, len(X)):
        # Remove all the special characters
        document = re.sub(r'W', ' ', str(X[sen]))
        
        # 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'^bs+', '', document)
        
        # Converting to Lowercase
        document = document.lower()
        
        # Lemmatization
        document = document.split()
    
        document = [stemmer.lemmatize(word) for word in document]
        document=" ".join(document)
        
        documents.append(document)
    

    En el script anterior usamos expresiones Regex de la biblioteca re de Python para realizar diferentes tareas de preprocesamiento. Comenzamos eliminando todos los caracteres que no sean palabras, como caracteres especiales, n煤meros, etc.

    A continuaci贸n, eliminamos todos los caracteres individuales. Por ejemplo, cuando quitamos el signo de puntuaci贸n de “David” y lo reemplazamos con un espacio, obtenemos “David” y un solo car谩cter “s”, que no tiene significado. Para eliminar esos caracteres individuales usamos s+[a-zA-Z]s+ expresi贸n regular que sustituye todos los caracteres individuales que tienen espacios a cada lado, con un solo espacio.

    A continuaci贸n, usamos el ^[a-zA-Z]s+ expresi贸n regular para reemplazar un solo car谩cter desde el principio del documento, con un solo espacio. Reemplazar caracteres individuales con un solo espacio puede resultar en m煤ltiples espacios, lo cual no es ideal.

    Usamos nuevamente la expresi贸n regular s+ para reemplazar uno o m谩s espacios con un solo espacio. Cuando tiene un conjunto de datos en formato de bytes, la letra del alfabeto “b” se agrega antes de cada cadena. La expresi贸n regular ^bs+ quita “b” del comienzo de una cadena. El siguiente paso es convertir los datos a min煤sculas para que las palabras que son realmente iguales pero que tienen diferentes casos se puedan tratar por igual.

    El 煤ltimo paso de preprocesamiento es el lematizaci贸n. En la lematizaci贸n, reducimos la palabra a la ra铆z del diccionario. Por ejemplo, “gatos” se convierte en “gato”. La lematizaci贸n se realiza para evitar la creaci贸n de caracter铆sticas que sean sem谩nticamente similares pero sint谩cticamente diferentes. Por ejemplo, no queremos dos caracter铆sticas diferentes llamadas “gatos” y “gato”, que son sem谩nticamente similares, por lo tanto, realizamos lematizaci贸n.

    Convertir texto en n煤meros

    Las m谩quinas, a diferencia de los humanos, no pueden comprender el texto en bruto. Las m谩quinas solo pueden ver n煤meros. En particular, las t茅cnicas estad铆sticas como el Machine Learning solo pueden tratar con n煤meros. Por lo tanto, necesitamos convertir nuestro texto en n煤meros.

    Existen diferentes enfoques para convertir texto en la forma num茅rica correspondiente. El modelo de la bolsa de palabras y el Modelo de incrustaci贸n de palabras son dos de los enfoques m谩s utilizados. En este art铆culo, usaremos el modelo de bolsa de palabras para convertir nuestro texto en n煤meros.

    Bolsa de palabras

    La siguiente secuencia de comandos usa el modelo de bolsa de palabras para convertir documentos de texto en las caracter铆sticas num茅ricas correspondientes:

    from sklearn.feature_extraction.text import CountVectorizer
    vectorizer = CountVectorizer(max_features=1500, min_df=5, max_df=0.7, stop_words=stopwords.words('english'))
    X = vectorizer.fit_transform(documents).toarray()
    

    El script anterior usa CountVectorizer clase de la sklearn.feature_extraction.text biblioteca. Hay algunos par谩metros importantes que deben pasarse al constructor de la clase. El primer par谩metro es el max_features , que se establece en 1500. Esto se debe a que cuando convierte palabras en n煤meros utilizando el enfoque de bolsa de palabras, todas las palabras 煤nicas en todos los documentos se convierten en caracter铆sticas. Todos los documentos pueden contener decenas de miles de palabras 煤nicas. Pero las palabras que tienen una frecuencia muy baja de ocurrencia inusualmente no son un buen par谩metro para clasificar documentos. Por lo tanto, establecemos el max_features par谩metro a 1500, lo que significa que queremos utilizar 1500 palabras m谩s frecuentes como caracter铆sticas para entrenar nuestro clasificador.

    El siguiente par谩metro es min_df y se ha establecido en 5. Esto corresponde al n煤mero m铆nimo de documentos que deben contener esta caracter铆stica. As铆 que solo incluimos aquellas palabras que aparecen en al menos 5 documentos. Del mismo modo, para el max_df, caracter铆stica el valor se establece en 0,7; en el que la fracci贸n corresponde a un porcentaje. Aqu铆 0,7 significa que debemos incluir solo aquellas palabras que aparecen en un m谩ximo del 70% de todos los documentos. Las palabras que aparecen en casi todos los documentos no suelen ser adecuadas para la clasificaci贸n porque no proporcionan ninguna informaci贸n 煤nica sobre el documento.

    Finalmente, quitamos el Para las palabras de nuestro texto ya que, en el caso del an谩lisis de sentimiento, las palabras vac铆as pueden no contener informaci贸n 煤til. Para eliminar las palabras vac铆as pasamos el stopwords objeto del nltk.corpus biblioteca a la stop_wordspar谩metro.

    los fit_transform funci贸n de la CountVectorizer class convierte documentos de texto en las funciones num茅ricas correspondientes.

    Encontrar TFIDF

    El enfoque de la bolsa de palabras funciona bien para convertir texto en n煤meros. Sin embargo, tiene un inconveniente. Asigna una puntuaci贸n a una palabra en funci贸n de su aparici贸n en un documento en particular. No tiene en cuenta el hecho de que la palabra tambi茅n puede aparecer con una frecuencia alta en otros documentos. TFIDF resuelve este problema multiplicando el t茅rmino frecuencia de una palabra por la frecuencia inversa del documento. TF significa “Frecuencia de t茅rmino”, mientras que IDF significa “Frecuencia de documento inversa”.

    El t茅rmino frecuencia se calcula como:

    Term frequency = (Number of Occurrences of a word)/(Total words in the document)
    

    Y la frecuencia inversa del documento se calcula como:

    IDF(word) = Log((Total number of documents)/(Number of documents containing the word))
    

    El valor de TFIDF para una palabra en un documento en particular es mayor si la frecuencia de aparici贸n de esa palabra es mayor en ese documento espec铆fico pero menor en todos los dem谩s documentos.

    Para convertir los valores obtenidos usando el modelo de bolsa de palabras en valores TFIDF, ejecute el siguiente script:

    from sklearn.feature_extraction.text import TfidfTransformer
    tfidfconverter = TfidfTransformer()
    X = tfidfconverter.fit_transform(X).toarray()
    
    Nota:

    Tambi茅n puede convertir directamente documentos de texto en valores de funciones TFIDF (sin convertir primero los documentos en funciones de bolsa de palabras) utilizando el siguiente script:

    from sklearn.feature_extraction.text import TfidfVectorizer
    tfidfconverter = TfidfVectorizer(max_features=1500, min_df=5, max_df=0.7, stop_words=stopwords.words('english'))
    X = tfidfconverter.fit_transform(documents).toarray()
    

    Conjuntos de entrenamiento y prueba

    Como cualquier otro problema de Machine Learning supervisado, necesitamos dividir nuestros datos en conjuntos de entrenamiento y prueba. Para hacerlo, usaremos el train_test_split utilidad de la sklearn.model_selection biblioteca. Ejecute el siguiente script:

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    

    El script anterior divide los datos en un 20% de conjunto de prueba y un 80% de conjunto de entrenamiento.

    Entrenamiento del modelo de clasificaci贸n de texto y predicci贸n del sentimiento

    Hemos dividido nuestros datos en conjuntos de entrenamiento y prueba. Ahora es el momento de ver la acci贸n real. Usaremos el algoritmo de bosque aleatorio para entrenar nuestro modelo. Puede utilizar cualquier otro modelo de su elecci贸n.

    Para entrenar nuestro modelo de Machine Learning usando el algoritmo de bosque aleatorio usaremos RandomForestClassifier clase de la sklearn.ensemble biblioteca. los fit El m茅todo de esta clase se utiliza para entrenar el algoritmo. Necesitamos pasar los datos de entrenamiento y los conjuntos de objetivos de entrenamiento a este m茅todo. Eche un vistazo al siguiente gui贸n:

    classifier = RandomForestClassifier(n_estimators=1000, random_state=0)
    classifier.fit(X_train, y_train) 
    

    Finalmente, para predecir el sentimiento de los documentos en nuestro conjunto de prueba, podemos usar el predict m茅todo del RandomForestClassifier clase como se muestra a continuaci贸n:

    y_pred = classifier.predict(X_test)
    

    Felicitaciones, ha entrenado con 茅xito su primer modelo de clasificaci贸n de texto y ha hecho algunas predicciones. Ahora es el momento de ver el rendimiento del modelo que acaba de crear.

    Evaluaci贸n del modelo

    Para evaluar el desempe帽o de un modelo de clasificaci贸n como el que acabamos de entrenar, podemos utilizar m茅tricas como la matriz de confusi贸n, Medida F1y la precisi贸n.

    Para encontrar estos valores, podemos usar classification_report, confusion_matrixy accuracy_score utilidades del sklearn.metrics biblioteca. Ejecute el siguiente script para hacerlo:

    from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
    
    print(confusion_matrix(y_test,y_pred))
    print(classification_report(y_test,y_pred))
    print(accuracy_score(y_test, y_pred))
    

    La salida se ve as铆:

    [[180  28]
     [ 30 162]]
                 precision    recall  f1-score   support
    
              0       0.86      0.87      0.86       208
              1       0.85      0.84      0.85       192
    
    avg / total       0.85      0.85      0.85       400
    
    0.855
    

    Del resultado, se puede ver que nuestro modelo logr贸 una precisi贸n del 85.5%, lo cual es muy bueno dado que elegimos aleatoriamente todos los par谩metros para CountVectorizer as铆 como para nuestro algoritmo de bosque aleatorio.

    Guardar y cargar el modelo

    En el script anterior, nuestro modelo de Machine Learning no tom贸 mucho tiempo para ejecutarse. Una de las razones del tiempo de entrenamiento r谩pido es el hecho de que ten铆amos un conjunto de entrenamiento relativamente m谩s peque帽o. Ten铆amos 2000 documentos, de los cuales usamos el 80% (1600) para capacitaci贸n. Sin embargo, en escenarios del mundo real, puede haber millones de documentos. En tales casos, puede llevar horas o incluso d铆as (si tiene m谩quinas m谩s lentas) entrenar los algoritmos. Por lo tanto, se recomienda guardar el modelo una vez entrenado.

    Podemos guardar nuestro modelo como pickle objeto en Python. Para hacerlo, ejecute el siguiente script:

    with open('text_classifier', 'wb') as picklefile:
        pickle.dump(classifier,picklefile)
    

    Una vez que ejecuta el script anterior, puede ver el text_classifier archivo en su directorio de trabajo. Hemos guardado nuestro modelo entrenado y podemos usarlo m谩s tarde para hacer predicciones directamente, sin entrenamiento.

    Para cargar el modelo, podemos utilizar el siguiente c贸digo:

    with open('text_classifier', 'rb') as training_model:
        model = pickle.load(training_model)
    

    Cargamos nuestro modelo entrenado y lo almacenamos en el model variable. Vamos a predecir el sentimiento para el conjunto de prueba usando nuestro modelo cargado y veamos si podemos obtener los mismos resultados. Ejecute el siguiente script:

    y_pred2 = model.predict(X_test)
    
    print(confusion_matrix(y_test, y_pred2))
    print(classification_report(y_test, y_pred2))
    print(accuracy_score(y_test, y_pred2)) 
    

    La salida se ve as铆:

    [[180  28]
     [ 30 162]]
                 precision    recall  f1-score   support
    
              0       0.86      0.87      0.86       208
              1       0.85      0.84      0.85       192
    
    avg / total       0.85      0.85      0.85       400
    
    0.855
    

    La salida es similar a la que obtuvimos anteriormente, que mostr贸 que guardamos y cargamos con 茅xito el modelo.

    Conclusi贸n

    La clasificaci贸n de texto es una de las tareas de PNL m谩s utilizadas. En este art铆culo, vimos un ejemplo simple de c贸mo se puede realizar la clasificaci贸n de texto en Python. Realizamos el an谩lisis sentimental de cr铆ticas de pel铆culas.

    Te aconsejo que cambies alg煤n otro algoritmo de Machine Learning para ver si puedes mejorar el rendimiento. Adem谩s, intente cambiar los par谩metros del CountVectorizerclase para ver si puede obtener alguna mejora.

     

    Etiquetas:

    Deja una respuesta

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