Introducción
Contenido
- 1 Introducción
- 2 Conjunto de datos
- 3 Análisis de sentimiento con Scikit-Learn
- 4 Convertir texto en números
- 5 Bolsa de palabras
- 6 Encontrar TFIDF
- 7 Conjuntos de entrenamiento y prueba
- 8 Entrenamiento del modelo de clasificación de texto y predicción del sentimiento
- 9 Evaluación del modelo
- 10 Guardar y cargar el modelo
- 11 Conclusió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.
Te puede interesar:Optimización del rendimiento de PythonConvertir 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_words
pará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».
Te puede interesar:Conversión de scripts de Python en archivos ejecutablesEl 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.
Te puede interesar:Python: enumerar archivos en un directorioPara 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_matrix
y 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.
Te puede interesar:Comprender las curvas ROC con PythonPodemos 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 CountVectorizer
clase para ver si puede obtener alguna mejora.