Curso
Descubrir temas es útil para muchos fines, como agrupar documentos, organizar contenido disponible en línea para la recuperación de información y hacer recomendaciones. Muchos proveedores de contenido y agencias de noticias utilizan modelos de temas para recomendar artículos a sus lectores. Del mismo modo, las empresas de selección los usan para extraer descripciones de puestos y relacionarlas con el conjunto de habilidades de las personas candidatas. Fíjate en el trabajo de data scientist: consiste en extraer el «conocimiento» de grandes volúmenes de datos recopilados. Normalmente, esos datos son no estructurados. Necesitas herramientas y técnicas potentes para analizar y entender grandes cantidades de datos no estructurados.
El modelado de temas es una técnica de minería de texto que ofrece métodos para identificar palabras clave que coaparecen y así resumir grandes colecciones de información textual. Ayuda a descubrir temas ocultos en los documentos, a anotar los documentos con esos temas y a organizar grandes volúmenes de datos no estructurados.
Modelado de temas
El modelado de temas descubre automáticamente los patrones temáticos ocultos en un conjunto de documentos. Es un algoritmo de analítica de texto no supervisado que se usa para encontrar grupos de palabras en un documento. Estos grupos de palabras representan un tema. Es posible que un mismo documento esté asociado a varios temas. Por ejemplo, palabras como "patient", "doctor", "disease", "cancer" y "health" representarían el tema "healthcare". El modelado de temas es un juego distinto a la búsqueda de texto basada en reglas que usa expresiones regulares.

Comparación entre clasificación de texto y modelado de temas
La clasificación de texto es un problema de aprendizaje automático supervisado, donde un documento o artículo se clasifica en un conjunto de clases predefinidas. El modelado de temas es el proceso de descubrir grupos de palabras que coaparecen en documentos de texto. Estos grupos de palabras relacionadas forman "temas". Es una forma de aprendizaje no supervisado, por lo que el conjunto de posibles temas es desconocido. El modelado de temas puede utilizarse para abordar el problema de clasificación de textos: el modelado de temas identifica los temas presentes en un documento, mientras que la clasificación asigna el texto a una sola clase.

Análisis semántico latente
LSA (Latent Semantic Analysis), también conocido como LSI (Latent Semantic Index), utiliza el modelo de bolsa de palabras (BoW), que da lugar a una matriz término-documento (ocurrencia de términos en un documento). Las filas representan términos y las columnas representan documentos. LSA aprende temas latentes realizando una descomposición matricial de la matriz término-documento mediante descomposición en valores singulares. LSA se utiliza habitualmente como técnica de reducción de dimensionalidad o de reducción de ruido.

Descomposición en valores singulares (SVD)
SVD es un método de factorización matricial que representa una matriz como el producto de otras dos matrices. Tiene aplicaciones muy útiles en procesamiento de señales, psicología, sociología, ciencias del clima y la atmósfera, estadística y astronomía.

- M es una matriz m×m
- U es una matriz singular izquierda m×n
- Σ es una matriz diagonal n×n con números reales no negativos.
- V es una matriz singular derecha m×n
- V* es una matriz n×m, que es la traspuesta de V.
Matriz identidad: es una matriz cuadrada en la que todos los elementos de la diagonal principal son unos y el resto son ceros.
Matriz diagonal: es una matriz en la que todas las entradas fuera de la diagonal principal son cero.
Matriz singular: una matriz es singular si su determinante es 0 o, dicho de otro modo, una matriz cuadrada que no tiene inversa.
Cómo determinar el número óptimo de temas
¿Cuál es la mejor forma de determinar k (número de temas) en el modelado de temas? Identificar el número óptimo de temas en un corpus dado es una tarea compleja. Podemos usar las siguientes opciones:
- Una forma es considerar cada tema como un clúster y evaluar su eficacia mediante el coeficiente de Silhouette.
- La medida de coherencia de temas es un indicador realista para identificar el número de temas.
La coherencia de temas es una métrica muy utilizada para evaluar modelos de temas. Usa modelos de variables latentes. Cada tema generado tiene una lista de palabras. En la medida de coherencia, se calcula la media/mediana de las similitudes por pares entre las palabras de un tema. Un valor alto de coherencia indica un buen modelo de temas.
Implementación de LSA con Gensim
Importar las librerías necesarias
#import modules
import os.path
from gensim import corpora
from gensim.models import LsiModel
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
from gensim.models.coherencemodel import CoherenceModel
import matplotlib.pyplot as plt
Cargar los datos
Primero, vamos a crear una función para cargar articles.csv. Puedes descargar los datos aquí.
def load_data(path,file_name):
"""
Input : path and file_name
Purpose: loading text file
Output : list of paragraphs/documents and
title(initial 100 words considred as title of document)
"""
documents_list = []
titles=[]
with open( os.path.join(path, file_name) ,"r") as fin:
for line in fin.readlines():
text = line.strip()
documents_list.append(text)
print("Total Number of Documents:",len(documents_list))
titles.append( text[0:min(len(text),100)] )
return documents_list,titles
Preprocesar los datos
Después de cargar los datos, necesitas preprocesar el texto. Estos son los pasos:
- Tokenizar los artículos
- Eliminar stop words
- Aplicar stemming al texto
def preprocess_data(doc_set):
"""
Input : docuemnt list
Purpose: preprocess text (tokenize, removing stopwords, and stemming)
Output : preprocessed text
"""
# initialize regex tokenizer
tokenizer = RegexpTokenizer(r'\w+')
# create English stop words list
en_stop = set(stopwords.words('english'))
# Create p_stemmer of class PorterStemmer
p_stemmer = PorterStemmer()
# list for tokenized documents in loop
texts = []
# loop through document list
for i in doc_set:
# clean and tokenize document string
raw = i.lower()
tokens = tokenizer.tokenize(raw)
# remove stop words from tokens
stopped_tokens = [i for i in tokens if not i in en_stop]
# stem tokens
stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]
# add tokens to list
texts.append(stemmed_tokens)
return texts
Preparar el corpus
El siguiente paso es preparar el corpus. Aquí creamos una matriz término-documento y un diccionario de términos.
def prepare_corpus(doc_clean):
"""
Input : clean document
Purpose: create term dictionary of our courpus and Converting list of documents (corpus) into Document Term Matrix
Output : term dictionary and Document Term Matrix
"""
# Creating the term dictionary of our courpus, where every unique term is assigned an index. dictionary = corpora.Dictionary(doc_clean)
dictionary = corpora.Dictionary(doc_clean)
# Converting list of documents (corpus) into Document Term Matrix using dictionary prepared above.
doc_term_matrix = [dictionary.doc2bow(doc) for doc in doc_clean]
# generate LDA model
return dictionary,doc_term_matrix
Crear un modelo LSA con Gensim
Tras crear el corpus, ya puedes generar un modelo con LSA.
def create_gensim_lsa_model(doc_clean,number_of_topics,words):
"""
Input : clean document, number of topics and number of words associated with each topic
Purpose: create LSA model using gensim
Output : return LSA model
"""
dictionary,doc_term_matrix=prepare_corpus(doc_clean)
# generate LSA model
lsamodel = LsiModel(doc_term_matrix, num_topics=number_of_topics, id2word = dictionary) # train model
print(lsamodel.print_topics(num_topics=number_of_topics, num_words=words))
return lsamodel
Determinar el número de temas
Hay que dar un paso adicional para optimizar los resultados identificando un número óptimo de temas. Aquí generaremos puntuaciones de coherencia para determinarlo.
def compute_coherence_values(dictionary, doc_term_matrix, doc_clean, stop, start=2, step=3):
"""
Input : dictionary : Gensim dictionary
corpus : Gensim corpus
texts : List of input texts
stop : Max num of topics
purpose : Compute c_v coherence for various number of topics
Output : model_list : List of LSA topic models
coherence_values : Coherence values corresponding to the LDA model with respective number of topics
"""
coherence_values = []
model_list = []
for num_topics in range(start, stop, step):
# generate LSA model
model = LsiModel(doc_term_matrix, num_topics=number_of_topics, id2word = dictionary) # train model
model_list.append(model)
coherencemodel = CoherenceModel(model=model, texts=doc_clean, dictionary=dictionary, coherence='c_v')
coherence_values.append(coherencemodel.get_coherence())
return model_list, coherence_values
Vamos a representar las puntuaciones de coherencia.
def plot_graph(doc_clean,start, stop, step):
dictionary,doc_term_matrix=prepare_corpus(doc_clean)
model_list, coherence_values = compute_coherence_values(dictionary, doc_term_matrix,doc_clean,
stop, start, step)
# Show graph
x = range(start, stop, step)
plt.plot(x, coherence_values)
plt.xlabel("Number of Topics")
plt.ylabel("Coherence score")
plt.legend(("coherence_values"), loc='best')
plt.show()
start,stop,step=2,12,1
plot_graph(clean_text,start,stop,step)

Este gráfico se interpreta fácilmente. En el eje X tienes el número de temas y en el eje Y la coherencia. De todos los valores, 7 temas tienen la mayor coherencia, así que el número óptimo de temas es 7.
Ejecutar todas las funciones anteriores
# LSA Model
number_of_topics=7
words=10
document_list,titles=load_data("","articles.txt")
clean_text=preprocess_data(document_list)
model=create_gensim_lsa_model(clean_text,number_of_topics,words)
Total Number of Documents: 4551
[(0, '0.361*"trump" + 0.272*"say" + 0.233*"said" + 0.166*"would" + 0.160*"clinton" + 0.140*"peopl" + 0.136*"one" + 0.126*"campaign" + 0.123*"year" + 0.110*"time"'), (1, '-0.389*"citi" + -0.370*"v" + -0.356*"h" + -0.355*"2016" + -0.354*"2017" + -0.164*"unit" + -0.159*"west" + -0.157*"manchest" + -0.116*"apr" + -0.112*"dec"'), (2, '0.612*"trump" + 0.264*"clinton" + -0.261*"eu" + -0.148*"say" + -0.137*"would" + 0.135*"donald" + -0.134*"leav" + -0.134*"uk" + 0.119*"republican" + -0.110*"cameron"'), (3, '-0.400*"min" + 0.261*"eu" + -0.183*"goal" + -0.152*"ball" + -0.132*"play" + 0.128*"said" + 0.128*"say" + -0.126*"leagu" + 0.122*"leav" + -0.122*"game"'), (4, '0.404*"bank" + -0.305*"eu" + -0.290*"min" + 0.189*"year" + -0.164*"leav" + -0.153*"cameron" + 0.143*"market" + 0.140*"rate" + -0.139*"vote" + -0.133*"say"'), (5, '0.310*"bank" + -0.307*"say" + -0.221*"peopl" + 0.203*"trump" + 0.166*"1" + 0.164*"min" + 0.163*"0" + 0.152*"eu" + 0.152*"market" + -0.138*"like"'), (6, '0.570*"say" + 0.237*"min" + -0.170*"vote" + 0.158*"govern" + -0.154*"poll" + 0.122*"tax" + 0.115*"statement" + 0.115*"bank" + 0.112*"budget" + -0.108*"one"')]
- Tema 1: "trump", "say", "said", "would", "clinton", "peopl", "one", "campaign","year","time" (elecciones presidenciales de EE. UU.)
- Tema 2: "citi", "v", "h", "2016", "2017","unit", "west", "manchest","apr" ,"dec" (Premier League inglesa)
- Tema 3: "trump","clinton", "eu","say","would","donald","leav","uk" ,"republican" ,"cameron" (elecciones presidenciales de EE. UU., Brexit)
- Tema 4: "min","eu","goal","ball","play","said","say","leagu","leav","game" (Premier League inglesa)
- Tema 5: "bank","eu","min","year","leav","cameron","market","rate","vote","say" (Brexit y situación de mercado)
- Tema 6: "bank","say","peopl","trump","1" ,"min" ,"eu","market" ,"like" (situación política y mercados)
- Tema 7: "say","min","vote","govern","poll","tax","statement","bank","budget","one" (elecciones en EE. UU. y planificación financiera)
Aquí hemos descubierto 7 temas usando análisis semántico latente. Algunos se solapan. Para capturar múltiples significados con mayor precisión conviene probar LDA (latent Dirichlet allocation). Te lo dejo como ejercicio: pruébalo con Gensim y cuéntanos qué tal.
Pros y contras de LSA
El algoritmo LSA es el método más sencillo: fácil de entender e implementar. Además, ofrece mejores resultados que el modelo de espacio vectorial. Es más rápido que otros algoritmos disponibles porque solo implica la descomposición de la matriz término-documento.
La dimensión de los temas latentes depende del rango de la matriz, por lo que no podemos superar ese límite. La matriz descompuesta por LSA es muy densa, lo que dificulta indexar dimensiones individuales. LSA no capta bien los múltiples significados de las palabras. Tampoco es más sencillo de implementar que LDA (latent Dirichlet allocation) y ofrece menor precisión que LDA.
Casos de uso del modelado de temas
Aplicaciones habituales de esta técnica incluyen el agrupamiento de documentos en análisis de texto, los sistemas de recomendación y la recuperación de información. Algunos casos de uso más detallados:
- Resumen de CV: ayuda a los recruiters a evaluar CV de un vistazo y reduce el esfuerzo de filtrar montones de candidaturas.
- Optimización para buscadores: se pueden etiquetar fácilmente artículos, blogs y documentos identificando los temas y sus palabras clave asociadas, lo que mejora los resultados de búsqueda.
- Optimización de sistemas de recomendación: actúan como filtro y asesor de información según el perfil y el historial del usuario. Pueden ayudar a descubrir contenido relevante aún no visitado en función de visitas anteriores.
- Mejora de la atención al cliente: descubrir temas relevantes y palabras clave asociadas en quejas y comentarios de clientes, por ejemplo, especificaciones de producto y servicio, departamento o sucursal. Esta información ayuda a dirigir la incidencia directamente al departamento correspondiente.
- Sanidad: el modelado de temas puede ayudar a extraer información útil y valiosa de informes médicos no estructurados, que puede emplearse en tratamientos de pacientes y en investigación médica.
Conclusión
En este tutorial has visto muchos detalles sobre el modelado de temas. Has aprendido qué es, qué es el análisis semántico latente, cómo construir los modelos correspondientes y cómo se generan los temas con LSA. También hemos repasado conceptos básicos como la descomposición en valores singulares y la puntuación de coherencia.
Esperamos que ahora puedas aplicar el modelado de temas para analizar tus propios datos. ¡Gracias por leer este tutorial!
Si quieres aprender más sobre Python, échale un vistazo al curso Case Studies in Statistical Thinking de DataCamp.