Cómo extraer palabras clave de texto con TF-IDF y Scikit-Learn de Python

En 2006, cuando tuve que usar TF-IDF para la extracción de palabras clave en Java, terminé escribiendo todo el código desde cero. Ni Data Science ni GitHub existían en ese entonces y las bibliotecas eran limitadas.

El mundo es muy diferente hoy. Tiene varias bibliotecas y repositorios de código fuente abierto en Github que brindan una implementación decente de TF-IDF. Si no necesita mucho control sobre cómo se calcula la matemática TF-IDF, le recomiendo que reutilice las bibliotecas de paquetes conocidos como Spark's MLLib o Python's scikit-learn.

El único problema que noté con estas bibliotecas es que están pensadas como un paso previo para otras tareas como agrupación, modelado de temas y clasificación de texto. TF-IDF se puede usar para extraer palabras clave importantes de un documento para tener una idea de lo que caracteriza a un documento. Por ejemplo, si se trata de artículos de Wikipedia, puede utilizar tf-idf para extraer palabras que son exclusivas de un artículo determinado. Estas palabras clave se pueden usar como un resumen muy simple de un documento y para análisis de texto cuando miramos estas palabras clave en conjunto.

En este artículo , le mostraré cómo puede usar scikit-learn para extraer palabras clave de documentos usando TF-IDF. Específicamente haremos esto en un conjunto de datos de desbordamiento de pila. Si desea acceder al Jupyter Notebook completo , diríjase a mi repositorio.

Nota importante: supongo que las personas que siguen este tutorial ya están familiarizadas con el concepto de TF-IDF. Si no es así, familiarícese con el concepto antes de seguir leyendo. Hay un par de videos en línea que brindan una explicación intuitiva de qué es. Para una explicación más académica, recomendaría la explicación de mi asesor de doctorado.

Conjunto de datos

En este ejemplo, usaremos un conjunto de datos de Stack Overflow que es un poco ruidoso y simula lo que podría estar tratando en la vida real. Puede encontrar este conjunto de datos en mi repositorio de tutoriales.

Observe que hay dos archivos . El archivo más grande, stackoverflow-data-idf.jsoncon 20.000 publicaciones, se utiliza para calcular la frecuencia inversa de documentos (IDF). El archivo más pequeño, stackoverflow-test.jsoncon 500 publicaciones, se usaría como un conjunto de prueba del que extraer palabras clave. Este conjunto de datos se basa en el volcado de Stack Overflow disponible públicamente de Big Query de Google.

Echemos un vistazo a nuestro conjunto de datos. El siguiente código lee una cadena json por línea desde data/stackoverflow-data-idf.jsonun marco de datos de pandas e imprime su esquema y el número total de publicaciones.

Aquí, lines=Truesimplemente significa que estamos tratando cada línea en el archivo de texto como una cadena json separada.

Tenga en cuenta que este conjunto de datos de Stack Overflow contiene 19 campos, incluido el título de la publicación, el cuerpo, las etiquetas, las fechas y otros metadatos que no necesitamos para este tutorial. Para este tutorial, lo que más nos interesa es el cuerpo y el título. Estos se convertirán en nuestra fuente de texto para la extracción de palabras clave.

Ahora crearemos un campo que combine ambos bodyy titleasí tendremos los dos en un campo. También imprimiremos la segunda entrada de texto en nuestro nuevo campo solo para ver cómo se ve el texto.

¡Oh, no parece muy legible! Bueno, eso se debe a toda la limpieza que se hizo pre_process(..). Puede hacer muchas más cosas pre_process(..), como eliminar todas las secciones de código y normalizar las palabras a su raíz. Para simplificar, realizaremos solo un preprocesamiento leve.

Crear vocabulario y recuento de palabras para las FDI

Ahora necesitamos crear el vocabulario y comenzar el proceso de conteo. Podemos usar CountVectorizer para crear un vocabulario a partir de todo el texto en nuestro df_idf['text'], seguido del conteo de palabras en el vocabulario:

El resultado de las dos últimas líneas del código anterior es una representación matricial dispersa de los recuentos. Cada columna representa una palabra del vocabulario. Cada fila representa el documento en nuestro conjunto de datos, donde los valores son los recuentos de palabras.

Tenga en cuenta que, con esta representación, el recuento de algunas palabras podría ser 0 si la palabra no aparece en el documento correspondiente.

Aquí estamos pasando dos parámetros a CountVectorizer max_dfy stop_words. La primera es simplemente ignorar todas las palabras que han aparecido en el 85% de los documentos, ya que pueden no ser importantes. La última es una lista personalizada de palabras vacías. También puede usar palabras vacías que son nativas de sklearn configurando stop_words='english'. La lista de palabras vacías utilizada para este tutorial se puede encontrar aquí.

La forma resultante de word_count_vectores (20000,124901) ya que tenemos 20,000 documentos en nuestro conjunto de datos (las filas) y el tamaño del vocabulario es 124,901.

En algunas aplicaciones de minería de texto, como la agrupación en clústeres y la clasificación de texto, normalmente limitamos el tamaño del vocabulario. Es realmente fácil hacer esto configurando max_features=vocab_sizeal crear una instancia de CountVectorizer. Para este tutorial, limitemos nuestro tamaño de vocabulario a 10,000:

Ahora, veamos 10 palabras de nuestro vocabulario:

['serializing', 'private', 'struct', 'public', 'class', 'contains', 'properties', 'string', 'serialize', 'attempt']

Dulce, estos están principalmente relacionados con la programación.

TfidfTransformer para calcular el IDF

Ahora es el momento de calcular los valores IDF.

En el siguiente código, esencialmente estamos tomando la matriz dispersa de CountVectorizer ( word_count_vector) para generar el IDF cuando invoca fit(...):

Punto extremadamente importante : el IDF siempre debe basarse en un corpus grande y debe ser representativo de los textos que utilizaría para extraer palabras clave. He visto varios artículos en la Web que calculan el IDF utilizando un puñado de documentos. Va a derrotar todo el propósito de la FID ponderando si no está basada en un gran corpus como:

  1. tu vocabulario se vuelve demasiado pequeño y
  2. tiene una capacidad limitada para observar el comportamiento de las palabras que conoce.

Calcular TF-IDF y extraer palabras clave

Una vez que tenemos nuestro IDF calculado, estamos listos para calcular TF-IDF y luego extraer las palabras clave principales de los vectores TF-IDF.

En este ejemplo, extraeremos las principales palabras clave para las preguntas en formato data/stackoverflow-test.json. Este archivo de datos tiene 500 preguntas con campos idénticos a los que data/stackoverflow-data-idf.jsonvimos anteriormente. Comenzaremos leyendo nuestro archivo de prueba, extrayendo los campos necesarios (título y cuerpo) y colocando los textos en una lista.

El siguiente paso es calcular el valor tf-idf para un documento dado en nuestro conjunto de prueba invocando tfidf_transformer.transform(...). Esto genera un vector de puntuaciones tf-idf.

A continuación, ordenamos las palabras en el vector en orden descendente de valores tf-idf y luego iteramos para extraer las n palabras clave principales. En el siguiente ejemplo, extraemos palabras clave para el primer documento de nuestro conjunto de prueba.

El sort_coo(...)método esencialmente ordena los valores en el vector mientras conserva el índice de la columna. Una vez que tenga el índice de la columna, es muy fácil buscar el valor de la palabra correspondiente, como vería en extract_topn_from_vector(...)donde lo hacemos feature_vals.append(feature_names[idx]).

¡Algunos resultados!

En esta sección, verá la pregunta de desbordamiento de pila seguida de las palabras clave extraídas correspondientes.

Pregunta sobre la integración del complemento Eclipse

A partir de las palabras clave anteriores, las principales palabras clave en realidad tienen sentido, se habla de eclipse, maven, integrate, war, y tomcat, que son todos únicos a esta pregunta específica.

Hay un par de palabras clave que podrían haberse eliminado, como possibilityy quizás incluso project. Puede hacer esto agregando palabras más comunes a su lista de detención. Incluso puede crear su propio conjunto de listas de exclusión, muy específicas para su dominio.

Ahora veamos otro ejemplo.

Pregunta sobre la importación de SQL

Incluso con todas las etiquetas html, debido al procesamiento previo, podemos extraer algunas palabras clave bastante buenas aquí. La última palabra appropriatelycalificaría como palabra de parada. Puede seguir ejecutando diferentes ejemplos para obtener ideas sobre cómo ajustar los resultados.

¡Voilà! ¡Ahora puede extraer palabras clave importantes de cualquier tipo de texto!

Recursos

  • Código fuente y conjunto de datos completos para este tutorial
  • Apilar datos de desbordamiento en BigQuery de Google

Siga mi blog para obtener más información sobre minería de textos, PNL y aprendizaje automático desde una perspectiva aplicada.

Este artículo se publicó originalmente en kavita-ganesan.com.