Curso
Descobrir tópicos é útil em várias frentes: clusterizar documentos, organizar conteúdos disponíveis online para busca e recomendações. Diversos provedores de conteúdo e agências de notícias usam modelos de tópicos para recomendar artigos aos leitores. Da mesma forma, empresas de recrutamento os utilizam para extrair descrições de vagas e mapeá-las com as competências dos candidatos. Veja o caso do cientista de dados: o trabalho é extrair "conhecimento" de grandes volumes de dados coletados. Em geral, esses dados são não estruturados. Você precisa de ferramentas e técnicas poderosas para analisar e entender grandes quantidades de texto não estruturado.
Topic modeling é uma técnica de mineração de texto que identifica palavras que ocorrem em conjunto para resumir grandes coleções de informação textual. Ela ajuda a descobrir tópicos ocultos no documento, anotar os documentos com esses tópicos e organizar grandes volumes de dados não estruturados.
Topic modeling
Topic modeling descobre automaticamente os temas ocultos a partir de documentos. É um algoritmo de análise de texto não supervisionado usado para encontrar grupos de palavras em um conjunto de documentos. Esses grupos de palavras representam um tópico. Um mesmo documento pode estar associado a vários temas. Por exemplo, um grupo de palavras como 'patient', 'doctor', 'disease', 'cancer' e 'health' representa o tópico 'healthcare'. Topic modeling é um jogo diferente de buscas baseadas em regras que usam expressões regulares.

Comparação entre classificação de texto e topic modeling
Classificação de texto é um problema de aprendizado de máquina supervisionado, no qual um documento ou artigo é classificado em um conjunto predefinido de classes. Topic modeling é o processo de descobrir grupos de palavras coocorrentes em documentos. Esses grupos de palavras relacionadas formam "tópicos". É uma forma de aprendizado não supervisionado, então o conjunto de tópicos possíveis é desconhecido. Topic modeling pode ser usado para ajudar a resolver o problema de classificação de texto. Enquanto o topic modeling identifica os tópicos presentes em um documento, a classificação de texto o classifica em uma única classe.

Latent Semantic Analysis
LSA (Latent Semantic Analysis), também conhecido como LSI (Latent Semantic Index), usa o modelo bag-of-words (BoW), que resulta em uma matriz termo-documento (ocorrência de termos em um documento). As linhas representam termos e as colunas representam documentos. O LSA aprende tópicos latentes realizando uma decomposição de matriz na matriz termo-documento usando a decomposição em valores singulares (SVD). LSA é tipicamente usado como técnica de redução de dimensionalidade ou redução de ruído.

Singular Value Decomposition (SVD)
SVD é um método de fatoração que representa uma matriz como o produto de duas (na prática, três) matrizes. Ele tem várias aplicações úteis em processamento de sinais, psicologia, sociologia, ciências do clima e atmosférica, estatística e astronomia.

- M é uma matriz m×m
- U é uma matriz singular à esquerda m×n
- Σ é uma matriz diagonal n×n com números reais não negativos
- V é uma matriz singular à direita m×n
- V* é uma matriz n×m, que é a transposta de V
Matriz identidade: é uma matriz quadrada em que todos os elementos da diagonal principal são uns e todos os demais são zeros.
Matriz diagonal: é uma matriz em que todas as entradas fora da diagonal principal são zero.
Matriz singular: uma matriz é singular se seu determinante é 0; isto é, uma matriz quadrada que não tem inversa.
Determinando o número ideal de tópicos
Qual é a melhor forma de definir k (número de tópicos) em topic modeling? Identificar o número ideal de tópicos em um corpus é uma tarefa desafiadora. Podemos usar as seguintes opções:
- Considerar cada tópico como um cluster e avaliar a eficácia do cluster usando o coeficiente de Silhouette.
- Usar a métrica de coerência de tópicos (topic coherence), uma medida prática para identificar o número de tópicos.
Topic coherence é uma métrica amplamente usada para avaliar modelos de tópicos. Ela se baseia em modelos de variáveis latentes. Cada tópico gerado traz uma lista de palavras. Na coerência de tópicos, calcula-se a média/mediana das pontuações de similaridade par a par entre as palavras de um tópico. Quanto maior a pontuação de coerência, melhor o modelo.
Implementando LSA com Gensim
Importar as bibliotecas necessárias
#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
Carregando os dados
Vamos primeiro criar uma função para carregar o arquivo articles.csv. Você pode baixar os dados aqui.
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
Pré-processando os dados
Depois de carregar os dados, você precisa pré-processar o texto. As etapas a seguir serão usadas:
- Tokenizar os artigos de texto
- Remover stopwords
- Aplicar stemming no 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 o corpus
O próximo passo é preparar o corpus. Aqui, você vai criar uma matriz termo-documento e um dicionário de termos.
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
Criar um modelo LSA com Gensim
Depois de criar o corpus, você pode gerar um modelo usando 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
Definir o número de tópicos
Mais um passo é necessário para otimizar os resultados: identificar a quantidade ideal de tópicos. Aqui, vamos gerar escores de coerência para determinar esse número.
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 plotar os valores de coerência.
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)

É fácil avaliar esse gráfico. No eixo X está o número de tópicos, e no eixo Y, o escore de coerência. Entre as opções, 7 tópicos apresentam a maior coerência; portanto, o número ideal de tópicos é 7.
Executar todas as funções acima
# 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"')]
- Tópico 1: "trump", "say", "said", "would", "clinton", "peopl", "one", "campaign","year","time" (eleições presidenciais dos EUA)
- Tópico 2: "citi", "v", "h", "2016", "2017","unit", "west", "manchest","apr" ,"dec" (Premier League inglesa)
- Tópico 3: "trump","clinton", "eu","say","would","donald","leav","uk" ,"republican" ,"cameron" (eleições nos EUA, Brexit)
- Tópico 4: "min","eu","goal","ball","play","said","say","leagu","leav","game" (Premier League inglesa)
- Tópico 5: "bank","eu","min","year","leav","cameron","market","rate","vote","say" (Brexit e condições de mercado)
- Tópico 6: "bank","say","peopl","trump","1" ,"min" ,"eu","market" ,"like" (situações políticas e mercado)
- Tópico 7: "say","min","vote","govern","poll","tax","statement","bank","budget","one" (eleições nos EUA e planejamento financeiro)
Aqui, 7 tópicos foram descobertos com Latent Semantic Analysis. Alguns se sobrepõem. Para capturar múltiplos significados com mais precisão, vale testar LDA (latent Dirichlet allocation). Fica como exercício: experimente no Gensim e compartilhe suas impressões.
Prós e contras do LSA
O algoritmo LSA é simples, fácil de entender e implementar. Ele costuma oferecer resultados melhores do que o modelo de espaço vetorial e é mais rápido que outros algoritmos, pois envolve apenas a decomposição da matriz termo-documento.
A dimensão dos tópicos latentes depende do posto (rank) da matriz, então não dá para ultrapassar esse limite. A matriz decomposta pelo LSA é altamente densa, o que dificulta indexar cada dimensão. O LSA não consegue capturar os múltiplos significados das palavras. Além disso, não é tão simples de implementar quanto o LDA e, em geral, entrega menor acurácia do que o LDA.
Casos de uso de topic modeling
Aplicações comuns incluem clusterização de documentos em análise de texto, sistemas de recomendação e recuperação de informação. Casos de uso mais detalhados:
- Resumo de currículos: ajuda recrutadores a avaliar rapidamente, reduzindo o esforço ao filtrar pilhas de CVs.
- SEO (otimização para mecanismos de busca): artigos, blogs e documentos online podem ser facilmente marcados ao identificar tópicos e palavras-chave associadas, melhorando os resultados de busca.
- Otimização de sistemas de recomendação: atuam como filtro e conselheiro com base no perfil e no histórico do usuário, ajudando a descobrir conteúdos relevantes ainda não visitados.
- Melhoria do suporte ao cliente: descobrir tópicos e palavras-chave relevantes em reclamações e feedbacks — por exemplo, especificações de produto/serviço, departamento e filial. Essas informações ajudam a direcionar a demanda diretamente ao setor correto.
- Saúde: topic modeling pode extrair informações úteis de laudos médicos não estruturados, auxiliando tratamentos de pacientes e pesquisas científicas.
Conclusão
Neste tutorial, você viu em detalhes o que é topic modeling, o que é Latent Semantic Analysis, como construir os respectivos modelos e como os tópicos são gerados com LSA. Também revisitamos conceitos como decomposição em valores singulares (SVD) e o escore de coerência.
Tomara que agora você consiga aplicar topic modeling para analisar seus próprios datasets. Obrigado por ler!
Se quiser aprender mais sobre Python, faça o curso Case Studies in Statistical Thinking da DataCamp.
