Clasificación de texto simple utilizando Fasttext

Clasificación de texto sencilla utilizando FastText

Crear un modelo de clasificación de texto con solo un conjunto de datos etiquetados, la biblioteca Fasttext y 10 minutos

Introducción

El procesamiento del lenguaje natural se está aplicando a casos de uso empresariales a un ritmo exponencialmente mayor. Una de las automatizaciones de IA más simples que puede transformar un negocio es la clasificación de texto, ya que en muchos casos, la clasificación de los datos de texto se realiza de manera manual en un proceso que consume mucho tiempo.

La clasificación de texto implica desarrollar una IA capaz de asignar etiquetas a un texto de entrada. Estos modelos de IA se pueden entrenar como un problema de aprendizaje supervisado, ajustando sus pesos basados en ejemplos previamente vistos con etiquetas correspondientes.

Para realizar la clasificación de texto en Python, podemos usar Fasttext. Fasttext es una biblioteca liviana y de código abierto en Python capaz de crear rápidamente modelos de clasificación de texto.

El conjunto de datos que utilizaré para esta demostración está disponible aquí. Este conjunto de datos consta de tweets relacionados con el coronavirus y sentimientos asociados. Hay cinco clases posibles: extremadamente negativo, negativo, neutral, positivo y extremadamente positivo. Utilizaremos fasttext para construir un modelo de IA para clasificar tweets utilizando este conjunto de datos.

Una cosa a tener en cuenta es que hay un área gris entre cada una de estas etiquetas: es decir, ¿dónde está la “línea” que separa positivo de extremadamente positivo? ¿O “negativo” de “extremadamente negativo”? Definitivamente, hay algunos tweets que caen en el medio de estas dos clases, y la etiqueta de la verdad absoluta podría ser subjetiva con respecto a qué lado de la línea termina la etiqueta. Como resultado, es poco probable que se logre una precisión de validación del 100%.

Si deseas probar el código tú mismo, el cuaderno de Kaggle está disponible aquí.

Procesamiento

A continuación se muestran algunas de las funciones de preprocesamiento clave utilizadas para preparar los datos para la entrada al modelo Fasttext. Ten en cuenta que estos pasos no limpian ni modifican el texto original de ninguna manera; me enfocaré únicamente en configurar los datos en el formato adecuado para la entrada al modelo de ML.

  1. process_data subselecciona las columnas de interés (texto y etiqueta asociada son todo lo que necesitamos). Para la etiqueta, agregamos la cadena “__label__”, ya que fasttext espera que las etiquetas tengan este prefijo.
  2. split_data divide los datos en un conjunto de entrenamiento, un conjunto de validación y un conjunto de pruebas.
  3. save_data_as_txt crea los archivos txt necesarios para fasttext. Fasttext espera un archivo txt que contenga texto y etiquetas asociadas, y eso es lo que crea esta función.
def process_data(df_train: pd.DataFrame, df_test: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame]:    df_train = df_train[["Sentiment", "OriginalTweet"]]    df_test = df_test[["Sentiment", "OriginalTweet"]]    df_train["Sentiment"] = df_train["Sentiment"].apply(lambda x: "__label__" + "_".join(a for a in x.split()))    df_test["Sentiment"] = df_test["Sentiment"].apply(lambda x: "__label__" + "_".join(a for a in x.split()))    return df_train, df_testdef split_data(df_train: pd.DataFrame, df_test: pd.DataFrame, train_fraction: float) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:    split_point = round(df_train.shape[0] * train_fraction)    df_train, df_val = df_train.iloc[:split_point], df_train.iloc[split_point:]    return df_train, df_val, df_testdef save_data_as_txt(df_train: pd.DataFrame, df_validation: pd.DataFrame, df_test: pd.DataFrame) -> None:    df_train.to_csv(train_filepath,index=False,sep=" ",header=None,quoting=csv.QUOTE_NONE,quotechar="",escapechar=" ",)    df_validation.to_csv(validation_filepath,index=False,sep=" ",header=None,quoting=csv.QUOTE_NONE,quotechar="",escapechar=" ",)    df_test.to_csv(test_filepath,index=False,sep=" ",header=None,quoting=csv.QUOTE_NONE,quotechar="",escapechar=" ",)

Ahora, simplemente configura algunas rutas y llama a las funciones anteriores, ¡y ya tenemos todos los datos listos para que Fasttext cree un modelo!

df_train = pd.read_csv("/kaggle/input/covid-19-nlp-text-classification/Corona_NLP_train.csv", encoding="latin1")df_test = pd.read_csv("/kaggle/input/covid-19-nlp-text-classification/Corona_NLP_test.csv", encoding="latin1")train_filepath = "df_train.txt"validation_filepath = "df_val.txt"test_filepath = "df_test.txt"df_train, df_test = process_data(df_train=df_train, df_test=df_test)df_train, df_validation, df_test = split_data(df_train=df_train, df_test=df_test, train_fraction=0.9)save_data_as_txt(df_train=df_train, df_validation=df_validation, df_test=df_test)

Ajuste del Modelo

En realidad, todo el trabajo duro ya está hecho. Para ajustar el modelo, simplemente llama al método

model = fasttext.train_supervised(input=str(train_filepath))

¡Y listo! Tenemos un modelo entrenado.

Aunque nuestro modelo está entrenado, no sabemos qué tan bien se desempeña. Vamos a escribir una función que devuelva la precisión promedio sobre todas las clases de etiquetas:

def obtener_precisión(modelo):    resultados_entrenamiento = modelo.test(path=train_filepath)    resultados_validación = modelo.test(path=validation_filepath)    resultados_prueba = modelo.test(path=test_filepath)    return resultados_entrenamiento, resultados_validación, resultados_prueba

Llamando a esta función con

resultados_entrenamiento, resultados_validación, resultados_prueba = obtener_precisión(modelo=model)print(resultados_entrenamiento, resultados_validación, resultados_prueba)

Revela una precisión de entrenamiento de referencia del 71.0%, una precisión de validación del 54.1% y una precisión de prueba del 48.4%. ¡Nada mal para un modelo de referencia!

También, como se mencionó en la introducción, si la inteligencia artificial clasifica un texto “extremadamente negativo” como “negativo”, esto se considera un error al calcular la precisión. Por lo tanto, muchos de los errores cometidos por el modelo son “desplazados por uno”, es decir, la etiqueta correcta era una de las etiquetas adyacentes.

Ajuste de Hiperparámetros

Hasta ahora, tenemos un modelo de referencia que ha mostrado resultados decentes. ¿Cómo podemos mejorar? Afortunadamente, hay varios hiperparámetros que se pueden pasar al método fasttext.train_supervised y que podríamos querer ajustar para ver si el modelo mejora su rendimiento.

Aquí es donde nuestra validación nos será útil: probaremos varios conjuntos diferentes de hiperparámetros y luego evaluaremos los modelos resultantes en el conjunto de validación. El conjunto de parámetros que resulte en la mayor precisión en el conjunto de validación será el que desearemos utilizar para nuestro modelo final.

¿Qué conjuntos de hiperparámetros deberíamos probar? Aunque podríamos intentar configurar manualmente los hiperparámetros y tratar de hacer mejoras nosotros mismos (o usar una biblioteca de ajuste de hiperparámetros como Optuna), yo soy demasiado perezoso para eso y prefiero simplemente usar una búsqueda aleatoria.

def crear_params_entrenamiento(referencia: bool = False) -> Dict[str, Any]:    if referencia:        return {}    epoch = random.randint(2, 120)    wordNgrams = random.randint(1, 6)    lr = np.random.uniform(0.02, 0.5)    dim = random.randint(50, 200)    minn = random.randint(0, 5)    maxn = random.randint(0, 5)    minCount = random.randint(1, 5)    ws = random.randint(2, 10)    lrUpdateRate = random.randint(50, 200)    bucket = random.randint(200000, 20000000)    return {        "epoch": epoch,        "wordNgrams": wordNgrams,        "lr": lr,        "dim": dim,        "minn": minn,        "maxn": maxn,        "minCount": minCount,        "lrUpdateRate": lrUpdateRate,        "ws": ws,        "bucket": bucket,        "thread": 12,    }

Esta función devolverá un conjunto de parámetros seleccionados al azar.

Podemos probar un solo conjunto de parámetros aleatorios simplemente ejecutando:

modelo = fasttext.train_supervised(input=str(train_filepath), **crear_params_entrenamiento())

Agreguemos un par de líneas adicionales para crear un pipeline de ajuste de hiperparámetros más completo. A continuación, declaramos el número de iteraciones a buscar e inicializamos la mejor_precisión actual como la precisión del modelo de referencia y los mejores_params actuales como un diccionario vacío (parámetros predeterminados).

Luego, ejecutamos un bucle donde cada iteración genera aleatoriamente los parámetros, entrena y evalúa el modelo. Si la nueva precisión es mayor que el registro anterior, sobrescribimos la mejor precisión y guardamos los mejores_params para referencia futura.

iteraciones = 10mejor_precisión, mejores_params = resultados_validación[1], {}for i in range(iteraciones):    params = crear_params_entrenamiento()    modelo = fasttext.train_supervised(input=str(train_filepath), **params)    resultados_entrenamiento, resultados_validación, resultados_prueba = obtener_precisión(modelo=modelo)    if resultados_validación[1] > mejor_precisión:        mejor_precisión = resultados_validación[1]        mejores_params = params    print(f"Mejor precisión hasta ahora: {mejor_precisión}")print(f"Mejores parámetros: {mejores_params}")

¡Al hacerlo, pudimos obtener una precisión final del 56.1%!

Conclusión

Investigando en los otros cuadernos que utilizan este conjunto de datos, puedo ver una solución de Naive Bayes con una precisión del 70%, o una solución de BERT que obtiene una precisión del 88%. Claramente, esto es mucho mejor que lo que obtuvimos con fasttext. Sin embargo, se aplicó una cantidad significativa de preprocesamiento de texto a los datos en esas implementaciones, algo que no hicimos.

Si los datos de texto no están limpios, la IA de fasttext podría considerar datos basura para tratar de encontrar patrones para etiquetar el texto. Los pasos adicionales para mejorar el rendimiento serían aplicar métodos de preprocesamiento al conjunto de datos. Además, hay más columnas de datos disponibles en el dataframe original que pueden ser útiles como entrada al modelo (solo usamos columnas de texto y etiquetas). Dejaré estos próximos pasos en tus manos, ya que el objetivo de este artículo es proporcionar una visión general genérica de la biblioteca fasttext.

Hemos aprendido:

  • Qué es la biblioteca fasttext
  • Cómo preprocesar un conjunto de datos para usarlo en fasttext
  • Cómo ajustar un modelo base en los datos
  • Cómo ajustar hiperparámetros de nuestro modelo para mejorar los resultados base

¡Gracias por leer hasta el final! Espero que esto te sea útil y buena suerte con tus tareas de clasificación de texto.

Enlaces:

Linkedin: https://www.linkedin.com/in/sergei-issaev/

Github: https://github.com/sergeiissaev

Kaggle: https://www.kaggle.com/sergei416

VoAGI: https://medium.com/@sergei740

Twitter: https://twitter.com/realSergAI

Aprende más sobre Vooban: https://vooban.com/es

We will continue to update Zepes; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

¿De quién es la responsabilidad de hacer que la IA generativa sea correcta?

Las posibilidades ilimitadas de la tecnología que trasciende fronteras.

Inteligencia Artificial

Por qué la NASA está enviando secretos nacionales a la Luna

NASA trabajará con la startup Lonestar y la Isla de Man para enviar una carga de datos a la Luna el próximo febrero, ...